Merge "Initial changes to add QuickSettings." into jb-mr1-dev

This commit is contained in:
Winson Chung
2012-09-08 15:54:20 -07:00
committed by Android (Google) Code Review
59 changed files with 1445 additions and 20 deletions

View File

@@ -16,6 +16,8 @@
<uses-permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- Networking and telephony -->
<uses-permission android:name="android.permission.BLUETOOTH" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<clip
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/stat_sys_battery_100"
android:clipOrientation="vertical"
android:gravity="bottom" />

View File

@@ -19,14 +19,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/settings_panel"
android:background="#80000080"
android:background="@drawable/notification_panel_bg"
>
<ImageView
<!-- TODO: Put into ScrollView -->
<com.android.systemui.statusbar.phone.QuickSettingsContainerView
android:id="@+id/quick_settings_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="@drawable/qs_coming_soon"
android:padding="4dp"
android:paddingBottom="@dimen/quick_settings_container_padding"
android:paddingLeft="@dimen/quick_settings_container_padding"
android:paddingRight="@dimen/quick_settings_container_padding"
android:animateLayoutChanges="true"
android:columnCount="@integer/quick_settings_num_columns"
/>
<LinearLayout android:id="@+id/handle"
android:layout_width="match_parent"

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<com.android.systemui.statusbar.phone.QuickSettingsTileView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="@dimen/quick_settings_cell_height"
android:background="#1B1D1B" />

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/airplane_mode_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/quick_settings_airplane_mode_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/battery_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:drawableTop="@drawable/ic_qs_battery"
android:text="@string/quick_settings_battery_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bluetooth_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/quick_settings_bluetooth_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:drawableTop="@drawable/ic_sysbar_brightness"
android:text="@string/quick_settings_brightness_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/quick_settings_ime_label"
android:singleLine="true"
/>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/location_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:drawableTop="@drawable/stat_sys_gps_acquiring"
android:text="@string/quick_settings_location_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/quick_settings_media_device_label"
android:singleLine="true"
/>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rssi_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/quick_settings_rssi_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:drawableTop="@drawable/ic_notify_quicksettings"
android:text="@string/quick_settings_settings_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<com.android.systemui.statusbar.policy.Clock
android:textAppearance="@style/TextAppearance.QuickSettings.Clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:singleLine="true"
/>
<com.android.systemui.statusbar.policy.QuickSettingsDateView
android:textAppearance="@style/TextAppearance.QuickSettings.Date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/user_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:gravity="center"
android:text="@string/quick_settings_user_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
android:background="#33000000"
/>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/wifi_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/quick_settings_wifi_label"
android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
/>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/quick_settings_wifi_display_label"
android:singleLine="true"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
/>

View File

@@ -23,5 +23,11 @@
<!-- Whether we're using the tablet-optimized recents interface (we use this
value at runtime for some things) -->
<integer name="status_bar_recents_bg_gradient_degrees">90</integer>
<!-- The number of columns in the QuickSettings -->
<integer name="quick_settings_num_columns">6</integer>
<!-- The number of columns that the top level tiles span in the QuickSettings -->
<integer name="quick_settings_user_time_settings_tile_span">2</integer>
</resources>

View File

@@ -37,4 +37,7 @@
<!-- Where to place the app icon over the thumbnail -->
<dimen name="status_bar_recents_app_icon_left_margin">8dp</dimen>
<dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
<!-- The fixed height of each tile -->
<dimen name="quick_settings_cell_height">100dp</dimen>
</resources>

View File

@@ -81,5 +81,11 @@
<!-- Min alpha % that recent items will fade to while being dismissed -->
<integer name="config_recent_item_min_alpha">3</integer>
<!-- The number of columns in the QuickSettings -->
<integer name="quick_settings_num_columns">3</integer>
<!-- The number of columns that the top level tiles span in the QuickSettings -->
<integer name="quick_settings_user_time_settings_tile_span">1</integer>
</resources>

View File

@@ -174,4 +174,14 @@
<!-- The distance you can pull a notificaiton before it pops open -->
<dimen name="one_finger_pop_limit">32dp</dimen>
<!-- The amount of padding around the QuickSettings tiles -->
<dimen name="quick_settings_container_padding">12dp</dimen>
<!-- The fixed height of each tile -->
<dimen name="quick_settings_cell_height">110dp</dimen>
<!-- The padding between each tile within the QuickSettings layout -->
<dimen name="quick_settings_cell_gap">5dp</dimen>
</resources>

View File

@@ -401,4 +401,34 @@
<!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
<string name="start_dreams">Start dreams</string>
<!-- QuickSettings: Airplane mode [CHAR LIMIT=NONE] -->
<string name="quick_settings_airplane_mode_label">Airplane mode</string>
<!-- QuickSettings: Battery [CHAR LIMIT=NONE] -->
<string name="quick_settings_battery_label">Battery</string>
<!-- QuickSettings: Bluetooth [CHAR LIMIT=NONE] -->
<string name="quick_settings_bluetooth_label">Bluetooth</string>
<!-- QuickSettings: Brightness [CHAR LIMIT=NONE] -->
<string name="quick_settings_brightness_label">Brightness</string>
<!-- QuickSettings: IME [CHAR LIMIT=NONE] -->
<string name="quick_settings_ime_label">IME</string>
<!-- QuickSettings: Location [CHAR LIMIT=NONE] -->
<string name="quick_settings_location_label">Location in use</string>
<!-- QuickSettings: Media device [CHAR LIMIT=NONE] -->
<string name="quick_settings_media_device_label">Media device</string>
<!-- QuickSettings: RSSI [CHAR LIMIT=NONE] -->
<string name="quick_settings_rssi_label">RSSI</string>
<!-- QuickSettings: RSSI (No network) [CHAR LIMIT=NONE] -->
<string name="quick_settings_rssi_emergency_only">Emergency Calls Only</string>
<!-- QuickSettings: Settings [CHAR LIMIT=NONE] -->
<string name="quick_settings_settings_label">Settings</string>
<!-- QuickSettings: Time [CHAR LIMIT=NONE] -->
<string name="quick_settings_time_label">Time</string>
<!-- QuickSettings: User [CHAR LIMIT=NONE] -->
<string name="quick_settings_user_label">Me</string>
<!-- QuickSettings: Wifi [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_label">Wifi</string>
<!-- QuickSettings: Wifi (No network) [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_no_network">No Network</string>
<!-- QuickSettings: Wifi display [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_display_label">Wifi display</string>
</resources>

View File

@@ -70,6 +70,28 @@
<style name="TextAppearance.StatusBar.Expanded.Network.EmergencyOnly">
</style>
<style name="TextAppearance" />
<style name="TextAppearance.QuickSettings" />
<style name="TextAppearance.QuickSettings.TileView">
<item name="android:padding">8dp</item>
<item name="android:textSize">13dp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">#ff8d908c</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">marquee</item>
<item name="android:fadingEdge">horizontal</item>
</style>
<style name="TextAppearance.QuickSettings.Clock" parent="@style/TextAppearance.QuickSettings.TileView">
<item name="android:textSize">24dp</item>
<item name="android:textColor">@android:color/holo_blue_light</item>
</style>
<style name="TextAppearance.QuickSettings.Date" parent="@style/TextAppearance.QuickSettings.TileView">
<item name="android:textSize">14dp</item>
</style>
<style name="Animation" />
<style name="Animation.ShirtPocketPanel">

View File

@@ -12,6 +12,10 @@ import android.view.View;
import android.widget.FrameLayout;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
public class PanelView extends FrameLayout {
public static final boolean DEBUG = false;
@@ -356,6 +360,11 @@ public class PanelView extends FrameLayout {
mBar = panelBar;
}
public void setup(NetworkController network, BluetoothController bt, BatteryController batt,
LocationController location) {
// To be implemented by classes extending PanelView
}
public void collapse() {
// TODO: abort animation or ongoing touch
if (mExpandedHeight > 0) {

View File

@@ -19,11 +19,10 @@ package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
@@ -31,7 +30,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
@@ -54,13 +52,11 @@ import android.util.Log;
import android.util.Slog;
import android.view.Display;
import android.view.Gravity;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManagerGlobal;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
@@ -76,7 +72,6 @@ import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.GestureRecorder;
@@ -86,6 +81,7 @@ import com.android.systemui.statusbar.RotationToggle;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.DateView;
import com.android.systemui.statusbar.policy.IntruderAlertView;
import com.android.systemui.statusbar.policy.LocationController;
@@ -139,6 +135,7 @@ public class PhoneStatusBar extends BaseStatusBar {
PhoneStatusBarPolicy mIconPolicy;
// These are no longer handled by the policy, because we need custom strategies for them
BluetoothController mBluetoothController;
BatteryController mBatteryController;
LocationController mLocationController;
NetworkController mNetworkController;
@@ -317,9 +314,6 @@ public class PhoneStatusBar extends BaseStatusBar {
View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
| (mNotificationPanelIsFullScreenWidth ? 0 : View.STATUS_BAR_DISABLE_SYSTEM_INFO));
// quick settings (WIP)
mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
if (!ActivityManager.isHighEndGfx()) {
mStatusBarWindow.setBackground(null);
mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
@@ -394,9 +388,11 @@ public class PhoneStatusBar extends BaseStatusBar {
mBatteryController = new BatteryController(mContext);
mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
mNetworkController = new NetworkController(mContext);
mBluetoothController = new BluetoothController(mContext);
final SignalClusterView signalCluster =
(SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
mNetworkController.addSignalCluster(signalCluster);
signalCluster.setNetworkController(mNetworkController);
@@ -434,6 +430,12 @@ public class PhoneStatusBar extends BaseStatusBar {
});
}
// Quick Settings (WIP)
mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
mSettingsPanel.setBar(mStatusBarView);
mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController,
mLocationController);
// final ImageView wimaxRSSI =
// (ImageView)sb.findViewById(R.id.wimax_signal);
// if (wimaxRSSI != null) {
@@ -1844,6 +1846,10 @@ public class PhoneStatusBar extends BaseStatusBar {
if (mClearButton instanceof TextView) {
((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
}
// Update the QuickSettings container
((SettingsPanelView) mSettingsPanel).updateResources();
loadDimens();
}

View File

@@ -0,0 +1,582 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.phone;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.ClipDrawable;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
class QuickSettingsModel implements BluetoothStateChangeCallback,
NetworkController.NetworkSignalChangedCallback,
BatteryController.BatteryStateChangeCallback,
LocationController.LocationGpsStateChangeCallback {
/** Represents the state of a given attribute. */
static class State {
int iconId;
String label;
boolean enabled;
}
static class BatteryState extends State {
int batteryLevel;
boolean pluggedIn;
}
/** The callback to update a given tile. */
interface RefreshCallback {
public void refreshView(QuickSettingsTileView view, State state);
}
private Context mContext;
private QuickSettingsTileView mUserTile;
private RefreshCallback mUserCallback;
private State mUserState = new State();
private QuickSettingsTileView mAirplaneModeTile;
private RefreshCallback mAirplaneModeCallback;
private State mAirplaneModeState = new State();
private QuickSettingsTileView mWifiTile;
private RefreshCallback mWifiCallback;
private State mWifiState = new State();
private QuickSettingsTileView mRSSITile;
private RefreshCallback mRSSICallback;
private State mRSSIState = new State();
private QuickSettingsTileView mBluetoothTile;
private RefreshCallback mBluetoothCallback;
private State mBluetoothState = new State();
private QuickSettingsTileView mBatteryTile;
private RefreshCallback mBatteryCallback;
private BatteryState mBatteryState = new BatteryState();
private QuickSettingsTileView mLocationTile;
private RefreshCallback mLocationCallback;
private State mLocationState = new State();
public QuickSettingsModel(Context context) {
mContext = context;
}
// User
void addUserTile(QuickSettingsTileView view, RefreshCallback cb) {
mUserTile = view;
mUserCallback = cb;
mUserCallback.refreshView(mUserTile, mUserState);
}
void setUserTileInfo(String name) {
mUserState.label = name;
mUserCallback.refreshView(mUserTile, mUserState);
}
// Airplane Mode
void addAirplaneModeTile(QuickSettingsTileView view, RefreshCallback cb) {
mAirplaneModeTile = view;
mAirplaneModeTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mAirplaneModeState.enabled) {
setAirplaneModeState(false);
} else {
setAirplaneModeState(true);
}
}
});
mAirplaneModeCallback = cb;
mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
}
private void setAirplaneModeState(boolean enabled) {
// TODO: Sets the view to be "awaiting" if not already awaiting
// Change the system setting
Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
enabled ? 1 : 0);
// TODO: Update the UI to reflect system setting
// mCheckBoxPref.setChecked(enabled);
// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enabled);
mContext.sendBroadcast(intent);
}
// NetworkSignalChanged callback
@Override
public void onAirplaneModeChanged(boolean enabled) {
// TODO: If view is in awaiting state, disable
Resources r = mContext.getResources();
mAirplaneModeState.enabled = enabled;
mAirplaneModeState.iconId = (enabled ?
R.drawable.ic_qs_airplane_enabled :
R.drawable.ic_qs_airplane_normal);
mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
}
// Wifi
void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
mWifiTile = view;
mWifiCallback = cb;
mWifiCallback.refreshView(mWifiTile, mWifiState);
}
// NetworkSignalChanged callback
@Override
public void onWifiSignalChanged(boolean enabled, String description) {
// TODO: If view is in awaiting state, disable
Resources r = mContext.getResources();
// TODO: Check if wifi is enabled
mWifiState.enabled = enabled;
mWifiState.iconId = (enabled ?
R.drawable.ic_qs_wifi_enabled :
R.drawable.ic_qs_wifi_normal);
mWifiState.label = (enabled ?
description :
r.getString(R.string.quick_settings_wifi_no_network));
mWifiCallback.refreshView(mWifiTile, mWifiState);
}
// RSSI
void addRSSITile(QuickSettingsTileView view, RefreshCallback cb) {
mRSSITile = view;
mRSSICallback = cb;
mRSSICallback.refreshView(mRSSITile, mRSSIState);
}
private void setRSSIState(boolean enabled) {
// TODO: Set RSSI enabled
// TODO: Sets the view to be "awaiting" if not already awaiting
}
// NetworkSignalChanged callback
@Override
public void onMobileDataSignalChanged(boolean enabled, String description) {
// TODO: If view is in awaiting state, disable
Resources r = mContext.getResources();
// TODO: Check if RSSI is enabled
mRSSIState.enabled = enabled;
mRSSIState.iconId = (enabled ?
R.drawable.ic_qs_rssi_enabled :
R.drawable.ic_qs_rssi_normal);
mRSSIState.label = (enabled ?
description :
r.getString(R.string.quick_settings_rssi_emergency_only));
mRSSICallback.refreshView(mRSSITile, mRSSIState);
}
// Bluetooth
void addBluetoothTile(QuickSettingsTileView view, RefreshCallback cb) {
mBluetoothTile = view;
mBluetoothTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBluetoothState.enabled) {
setBluetoothState(false);
} else {
setBluetoothState(true);
}
}
});
mBluetoothCallback = cb;
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
onBluetoothStateChange(adapter.isEnabled());
}
private void setBluetoothState(boolean enabled) {
// TODO: Sets the view to be "awaiting" if not already awaiting
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
if (enabled) {
adapter.enable();
} else {
adapter.disable();
}
}
}
// BluetoothController callback
@Override
public void onBluetoothStateChange(boolean on) {
// TODO: If view is in awaiting state, disable
Resources r = mContext.getResources();
mBluetoothState.enabled = on;
if (on) {
mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_enabled;
} else {
mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_normal;
}
mBluetoothCallback.refreshView(mBluetoothTile, mBluetoothState);
}
// Battery
void addBatteryTile(QuickSettingsTileView view, RefreshCallback cb) {
mBatteryTile = view;
mBatteryCallback = cb;
mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
}
// BatteryController callback
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn) {
mBatteryState.batteryLevel = level;
mBatteryState.pluggedIn = pluggedIn;
mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
}
// Location
void addLocationTile(QuickSettingsTileView view, RefreshCallback cb) {
mLocationTile = view;
mLocationCallback = cb;
mLocationCallback.refreshView(mLocationTile, mLocationState);
disableLocationTile();
}
private void enableLocationTile() {
mLocationTile.setVisibility(View.VISIBLE);
}
private void disableLocationTile() {
mLocationTile.setVisibility(View.GONE);
}
// LocationController callback
@Override
public void onLocationGpsStateChanged(boolean inUse, String description) {
if (inUse) {
mLocationState.enabled = inUse;
mLocationState.label = description;
mLocationCallback.refreshView(mLocationTile, mLocationState);
enableLocationTile();
} else {
disableLocationTile();
}
}
}
/**
*
*/
class QuickSettings {
private Context mContext;
private PanelBar mBar;
private QuickSettingsModel mModel;
private QuickSettingsContainerView mContainerView;
private CursorLoader mUserInfoLoader;
// The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
// configuration change)
private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
new ArrayList<QuickSettingsTileView>();
public QuickSettings(Context context, QuickSettingsContainerView container) {
mContext = context;
mModel = new QuickSettingsModel(context);
mContainerView = container;
setupQuickSettings();
updateResources();
}
void setBar(PanelBar bar) {
mBar = bar;
}
void setup(NetworkController networkController, BluetoothController bluetoothController,
BatteryController batteryController, LocationController locationController) {
networkController.addNetworkSignalChangedCallback(mModel);
bluetoothController.addStateChangedCallback(mModel);
batteryController.addStateChangedCallback(mModel);
locationController.addStateChangedCallback(mModel);
}
private void queryForUserInformation() {
Uri userContactUri = Uri.withAppendedPath(
ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
String[] selectArgs = {
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Photo.PHOTO
};
String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.RawContacts.ACCOUNT_TYPE);
String[] whereArgs = {
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
};
mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
null);
mUserInfoLoader.registerListener(0,
new Loader.OnLoadCompleteListener<Cursor>() {
@Override
public void onLoadComplete(Loader<Cursor> loader,
Cursor cursor) {
if (cursor.moveToFirst()) {
String name = cursor.getString(0); // DISPLAY_NAME
mModel.setUserTileInfo(name);
/*
byte[] photoData = cursor.getBlob(0);
Bitmap b =
BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
*/
}
mUserInfoLoader.stopLoading();
}
});
mUserInfoLoader.startLoading();
}
private void setupQuickSettings() {
// Setup the tiles that we are going to be showing (including the temporary ones)
LayoutInflater inflater = LayoutInflater.from(mContext);
addUserTiles(mContainerView, inflater);
addSystemTiles(mContainerView, inflater);
addTemporaryTiles(mContainerView, inflater);
queryForUserInformation();
}
private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
QuickSettingsTileView userTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
userTile.setContent(R.layout.quick_settings_tile_user, inflater);
mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.user_textview);
tv.setText(state.label);
}
});
parent.addView(userTile);
mDynamicSpannedTiles.add(userTile);
// Time tile
QuickSettingsTileView timeTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
parent.addView(timeTile);
mDynamicSpannedTiles.add(timeTile);
// Settings tile
QuickSettingsTileView settingsTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater);
settingsTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mBar.collapseAllPanels(true);
}
});
parent.addView(settingsTile);
mDynamicSpannedTiles.add(settingsTile);
}
private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
// Wi-fi
QuickSettingsTileView wifiTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
wifiTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mBar.collapseAllPanels(true);
}
});
mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.wifi_textview);
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
tv.setText(state.label);
}
});
parent.addView(wifiTile);
// RSSI
QuickSettingsTileView rssiTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
rssiTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mBar.collapseAllPanels(true);
}
});
mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
tv.setText(state.label);
}
});
parent.addView(rssiTile);
// Battery
QuickSettingsTileView batteryTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
batteryTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mBar.collapseAllPanels(true);
}
});
mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
QuickSettingsModel.BatteryState batteryState =
(QuickSettingsModel.BatteryState) state;
TextView tv = (TextView) view.findViewById(R.id.battery_textview);
ClipDrawable drawable = (ClipDrawable) tv.getCompoundDrawables()[1];
drawable.setLevel((int) (10000 * (batteryState.batteryLevel / 100.0f)));
// TODO: use format string
tv.setText(batteryState.batteryLevel + "%");
}
});
parent.addView(batteryTile);
// Airplane Mode
QuickSettingsTileView airplaneTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater);
mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview);
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
}
});
parent.addView(airplaneTile);
// Bluetooth
QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
}
});
parent.addView(bluetoothTile);
// Brightness
QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
brightnessTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.Settings.ACTION_DISPLAY_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mBar.collapseAllPanels(true);
}
});
parent.addView(brightnessTile);
}
private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
// Location
QuickSettingsTileView locationTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
locationTile.setContent(R.layout.quick_settings_tile_location, inflater);
locationTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent =
new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mBar.collapseAllPanels(true);
}
});
mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.location_textview);
tv.setText(state.label);
}
});
parent.addView(locationTile);
/*
QuickSettingsTileView mediaTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
parent.addView(mediaTile);
QuickSettingsTileView imeTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
imeTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
parent.removeViewAt(0);
}
});
parent.addView(imeTile);
*/
}
void updateResources() {
Resources r = mContext.getResources();
// Update the User, Time, and Settings tiles spans, and reset everything else
int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
for (QuickSettingsTileView v : mDynamicSpannedTiles) {
v.setColumnSpan(span);
}
mContainerView.requestLayout();
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.phone;
import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.android.systemui.R;
/**
*
*/
class QuickSettingsContainerView extends FrameLayout {
// The number of columns in the QuickSettings grid
private int mNumColumns;
// The gap between tiles in the QuickSettings grid
private float mCellGap;
public QuickSettingsContainerView(Context context, AttributeSet attrs) {
super(context, attrs);
updateResources();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// TODO: Setup the layout transitions
LayoutTransition transitions = getLayoutTransition();
}
void updateResources() {
Resources r = getContext().getResources();
mCellGap = r.getDimension(R.dimen.quick_settings_cell_gap);
mNumColumns = r.getInteger(R.integer.quick_settings_num_columns);
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Calculate the cell width dynamically
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() -
(mNumColumns - 1) * mCellGap);
float cellWidth = availableWidth / mNumColumns;
// Update each of the children's widths accordingly to the cell width
int N = getChildCount();
int cellHeight = 0;
int cursor = 0;
for (int i = 0; i < N; ++i) {
// Update the child's width
QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i);
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
int colSpan = v.getColumnSpan();
lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGap);
// Measure the child
v.setMinimumWidth(lp.width);
v.setMinimumHeight(lp.height);
int newWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.AT_MOST);
int newHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.AT_MOST);
v.measure(newWidthSpec, newHeightSpec);
// Save the cell height
if (cellHeight <= 0) {
cellHeight = v.getMeasuredHeight();
}
cursor += colSpan;
}
// Set the measured dimensions. We always fill the tray width, but wrap to the height of
// all the tiles.
int numRows = (int) Math.ceil((float) cursor / mNumColumns);
int newHeight = (int) ((numRows * cellHeight) + ((numRows - 1) * mCellGap)) +
getPaddingTop() + getPaddingBottom();
setMeasuredDimension(width, newHeight);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int N = getChildCount();
int x = getPaddingLeft();
int y = getPaddingTop();
int cursor = 0;
for (int i = 0; i < N; ++i) {
QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i);
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) v.getLayoutParams();
if (v.getVisibility() != GONE) {
int col = cursor % mNumColumns;
int colSpan = v.getColumnSpan();
int row = (int) (cursor / mNumColumns);
// Push the item to the next row if it can't fit on this one
if ((col + colSpan) > mNumColumns) {
x = getPaddingLeft();
y += lp.height + mCellGap;
row++;
}
// Layout the container
v.layout(x, y, x + lp.width, y + lp.height);
// Offset the position by the cell gap or reset the position and cursor when we
// reach the end of the row
cursor += v.getColumnSpan();
if (cursor < (((row + 1) * mNumColumns))) {
x += lp.width + mCellGap;
} else {
x = getPaddingLeft();
y += lp.height + mCellGap;
}
}
}
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
/**
*
*/
class QuickSettingsTileView extends FrameLayout {
private int mColSpan;
private int mRowSpan;
private int mCellWidth;
public QuickSettingsTileView(Context context, AttributeSet attrs) {
super(context, attrs);
mColSpan = 1;
mRowSpan = 1;
}
void setColumnSpan(int span) {
mColSpan = span;
}
int getColumnSpan() {
return mColSpan;
}
void setContent(int layoutId, LayoutInflater inflater) {
inflater.inflate(layoutId, this);
}
}

View File

@@ -16,14 +16,69 @@
package com.android.systemui.statusbar.phone;
import android.animation.LayoutTransition;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
public class SettingsPanelView extends PanelView {
private QuickSettings mQS;
private QuickSettingsContainerView mQSContainer;
public SettingsPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mQSContainer = (QuickSettingsContainerView) findViewById(R.id.quick_settings_container);
mQS = new QuickSettings(getContext(), mQSContainer);
}
@Override
public void setBar(PanelBar panelBar) {
super.setBar(panelBar);
if (mQS != null) {
mQS.setBar(panelBar);
}
}
@Override
public void setup(NetworkController networkController, BluetoothController bluetoothController,
BatteryController batteryController, LocationController locationController) {
super.setup(networkController, bluetoothController, batteryController, locationController);
if (mQS != null) {
mQS.setup(networkController, bluetoothController, batteryController,
locationController);
}
}
void updateResources() {
if (mQS != null) {
mQS.updateResources();
}
if (mQSContainer != null) {
mQSContainer.updateResources();
}
requestLayout();
}
@Override
public void fling(float vel, boolean always) {
((PhoneStatusBarView) mBar).mBar.getGestureRecorder().tag(

View File

@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy;
import java.util.ArrayList;
import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -36,6 +37,13 @@ public class BatteryController extends BroadcastReceiver {
private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>();
private ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
private ArrayList<BatteryStateChangeCallback> mChangeCallbacks =
new ArrayList<BatteryStateChangeCallback>();
public interface BatteryStateChangeCallback {
public void onBatteryLevelChanged(int level, boolean pluggedIn);
}
public BatteryController(Context context) {
mContext = context;
@@ -52,6 +60,10 @@ public class BatteryController extends BroadcastReceiver {
mLabelViews.add(v);
}
public void addStateChangedCallback(BatteryStateChangeCallback cb) {
mChangeCallbacks.add(cb);
}
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
@@ -73,6 +85,10 @@ public class BatteryController extends BroadcastReceiver {
v.setText(mContext.getString(R.string.status_bar_settings_battery_meter_format,
level));
}
for (BatteryStateChangeCallback cb : mChangeCallbacks) {
cb.onBatteryLevelChanged(level, plugged);
}
}
}
}

View File

@@ -16,9 +16,8 @@
package com.android.systemui.statusbar.policy;
import java.util.ArrayList;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -26,6 +25,8 @@ import android.content.IntentFilter;
import android.view.View;
import android.widget.ImageView;
import java.util.ArrayList;
import com.android.systemui.R;
public class BluetoothController extends BroadcastReceiver {
@@ -38,6 +39,9 @@ public class BluetoothController extends BroadcastReceiver {
private int mContentDescriptionId = 0;
private boolean mEnabled = false;
private ArrayList<BluetoothStateChangeCallback> mChangeCallbacks =
new ArrayList<BluetoothStateChangeCallback>();
public BluetoothController(Context context) {
mContext = context;
@@ -58,6 +62,10 @@ public class BluetoothController extends BroadcastReceiver {
mIconViews.add(v);
}
public void addStateChangedCallback(BluetoothStateChangeCallback cb) {
mChangeCallbacks.add(cb);
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
@@ -98,5 +106,8 @@ public class BluetoothController extends BroadcastReceiver {
? null
: mContext.getString(mContentDescriptionId));
}
for (BluetoothStateChangeCallback cb : mChangeCallbacks) {
cb.onBluetoothStateChange(mEnabled);
}
}
}

View File

@@ -30,7 +30,7 @@ import com.android.systemui.R;
import java.util.Date;
public final class DateView extends TextView {
public class DateView extends TextView {
private static final String TAG = "DateView";
private boolean mAttachedToWindow;
@@ -86,7 +86,7 @@ public final class DateView extends TextView {
return 0;
}
private final void updateClock() {
protected void updateClock() {
final Context context = getContext();
Date now = new Date();
CharSequence dow = DateFormat.format("EEEE", now);

View File

@@ -37,6 +37,7 @@ import android.app.INotificationManager;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
public class LocationController extends BroadcastReceiver {
private static final String TAG = "StatusBar.LocationController";
@@ -47,6 +48,13 @@ public class LocationController extends BroadcastReceiver {
private INotificationManager mNotificationService;
private ArrayList<LocationGpsStateChangeCallback> mChangeCallbacks =
new ArrayList<LocationGpsStateChangeCallback>();
public interface LocationGpsStateChangeCallback {
public void onLocationGpsStateChanged(boolean inUse, String description);
}
public LocationController(Context context) {
mContext = context;
@@ -60,6 +68,10 @@ public class LocationController extends BroadcastReceiver {
mNotificationService = nm.getService();
}
public void addStateChangedCallback(LocationGpsStateChangeCallback cb) {
mChangeCallbacks.add(cb);
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
@@ -89,12 +101,14 @@ public class LocationController extends BroadcastReceiver {
if (visible) {
Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
gpsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0,
gpsIntent, 0, null, UserHandle.CURRENT);
String text = mContext.getText(textResId).toString();
Notification n = new Notification.Builder(mContext)
.setSmallIcon(iconId)
.setContentTitle(mContext.getText(textResId))
.setContentTitle(text)
.setOngoing(true)
.setContentIntent(pendingIntent)
.getNotification();
@@ -117,6 +131,10 @@ public class LocationController extends BroadcastReceiver {
mNotificationService.cancelNotificationWithTag(
mContext.getPackageName(), null,
GPS_NOTIFICATION_ID, UserHandle.USER_CURRENT);
for (LocationGpsStateChangeCallback cb : mChangeCallbacks) {
cb.onLocationGpsStateChanged(false, null);
}
}
} catch (android.os.RemoteException ex) {
// well, it was worth a shot

View File

@@ -148,6 +148,8 @@ public class NetworkController extends BroadcastReceiver {
ArrayList<TextView> mWifiLabelViews = new ArrayList<TextView>();
ArrayList<TextView> mEmergencyLabelViews = new ArrayList<TextView>();
ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
ArrayList<NetworkSignalChangedCallback> mSignalsChangedCallbacks =
new ArrayList<NetworkSignalChangedCallback>();
int mLastPhoneSignalIconId = -1;
int mLastDataDirectionIconId = -1;
int mLastDataDirectionOverlayIconId = -1;
@@ -172,6 +174,12 @@ public class NetworkController extends BroadcastReceiver {
void setIsAirplaneMode(boolean is, int airplaneIcon);
}
public interface NetworkSignalChangedCallback {
void onWifiSignalChanged(boolean enabled, String description);
void onMobileDataSignalChanged(boolean enabled, String description);
void onAirplaneModeChanged(boolean enabled);
}
/**
* Construct this controller object and register for updates.
*/
@@ -299,6 +307,11 @@ public class NetworkController extends BroadcastReceiver {
refreshSignalCluster(cluster);
}
public void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
mSignalsChangedCallbacks.add(cb);
notifySignalsChangedCallbacks(cb);
}
public void refreshSignalCluster(SignalCluster cluster) {
cluster.setWifiIndicators(
// only show wifi in the cluster if connected or if wifi-only
@@ -329,6 +342,27 @@ public class NetworkController extends BroadcastReceiver {
cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId);
}
void notifySignalsChangedCallbacks(NetworkSignalChangedCallback cb) {
// only show wifi in the cluster if connected or if wifi-only
boolean wifiEnabled = mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature);
String wifiDesc = wifiEnabled ?
mWifiSsid : null;
cb.onWifiSignalChanged(wifiEnabled, wifiDesc);
if (isEmergencyOnly()) {
cb.onMobileDataSignalChanged(false, null);
} else {
if (mIsWimaxEnabled && mWimaxConnected) {
// wimax is special
cb.onMobileDataSignalChanged(true, mNetworkName);
} else {
// normal mobile data
cb.onMobileDataSignalChanged(mHasMobileDataFeature, mNetworkName);
}
}
cb.onAirplaneModeChanged(mAirplaneMode);
}
public void setStackedMode(boolean stacked) {
mDataAndWifiStacked = true;
}
@@ -1124,6 +1158,9 @@ public class NetworkController extends BroadcastReceiver {
for (SignalCluster cluster : mSignalClusters) {
refreshSignalCluster(cluster);
}
for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
notifySignalsChangedCallbacks(cb);
}
}
if (mLastAirplaneMode != mAirplaneMode) {

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.policy;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewParent;
import android.widget.TextView;
import com.android.systemui.R;
import java.util.Date;
public final class QuickSettingsDateView extends DateView {
public QuickSettingsDateView(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void updateClock() {
final Context context = getContext();
Date now = new Date();
CharSequence dow = DateFormat.format("MMM d, yyyy", now);
setText(dow);
}
}