livedisplay: Publish our own damn tile!

Change-Id: If765cb1fe1cbc34c857dc6237cd25a1fb27f848e
This commit is contained in:
Steve Kondik 2016-04-13 18:14:32 -07:00 committed by Steve Kondik
parent 763e39ad54
commit 712426f249
9 changed files with 332 additions and 2 deletions

View File

@ -15,14 +15,25 @@
*/
package org.cyanogenmod.platform.internal.display;
import static cyanogenmod.hardware.LiveDisplayManager.FEATURE_MANAGED_OUTDOOR_MODE;
import static cyanogenmod.hardware.LiveDisplayManager.MODE_DAY;
import static cyanogenmod.hardware.LiveDisplayManager.MODE_FIRST;
import static cyanogenmod.hardware.LiveDisplayManager.MODE_LAST;
import static cyanogenmod.hardware.LiveDisplayManager.MODE_OUTDOOR;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@ -33,6 +44,7 @@ import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
@ -41,6 +53,10 @@ import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
import org.cyanogenmod.internal.util.QSConstants;
import org.cyanogenmod.internal.util.QSUtils;
import org.cyanogenmod.platform.internal.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@ -49,12 +65,12 @@ import java.util.Iterator;
import java.util.List;
import cyanogenmod.app.CMContextConstants;
import cyanogenmod.app.CMStatusBarManager;
import cyanogenmod.app.CustomTile;
import cyanogenmod.hardware.ILiveDisplayService;
import cyanogenmod.hardware.LiveDisplayConfig;
import cyanogenmod.providers.CMSettings;
import static cyanogenmod.hardware.LiveDisplayManager.*;
/**
* LiveDisplay is an advanced set of features for improving
* display quality under various ambient conditions.
@ -96,6 +112,16 @@ public class LiveDisplayService extends SystemService {
private LiveDisplayConfig mConfig;
// QS tile
private String[] mTileEntries;
private String[] mTileDescriptionEntries;
private String[] mTileAnnouncementEntries;
private String[] mTileValues;
private int[] mTileEntryIconRes;
private static String ACTION_NEXT_MODE = "cyanogenmod.hardware.NEXT_LIVEDISPLAY_MODE";
private static String EXTRA_NEXT_MODE = "next_mode";
public LiveDisplayService(Context context) {
super(context);
@ -106,6 +132,8 @@ public class LiveDisplayService extends SystemService {
Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
mHandlerThread.start();
mHandler = new LiveDisplayHandler(mHandlerThread.getLooper());
updateCustomTileEntries();
}
@Override
@ -169,10 +197,125 @@ public class LiveDisplayService extends SystemService {
mModeObserver = new ModeObserver(mHandler);
mModeObserver.update();
mContext.registerReceiver(mNextModeReceiver,
new IntentFilter(ACTION_NEXT_MODE));
publishCustomTile();
mInitialized = true;
}
}
private void updateCustomTileEntries() {
Resources res = mContext.getResources();
mTileEntries = res.getStringArray(R.array.live_display_entries);
mTileDescriptionEntries = res.getStringArray(R.array.live_display_description);
mTileAnnouncementEntries = res.getStringArray(R.array.live_display_announcement);
mTileValues = res.getStringArray(R.array.live_display_values);
TypedArray typedArray = res.obtainTypedArray(R.array.live_display_drawables);
mTileEntryIconRes = new int[typedArray.length()];
for (int i = 0; i < mTileEntryIconRes.length; i++) {
mTileEntryIconRes[i] = typedArray.getResourceId(i, 0);
}
typedArray.recycle();
}
private int getCurrentModeIndex() {
return ArrayUtils.indexOf(mTileValues, String.valueOf(mModeObserver.getMode()));
}
private int getNextModeIndex() {
int next = getCurrentModeIndex() + 1;
if (next >= mTileValues.length) {
next = 0;
}
int nextMode = 0;
while (true) {
nextMode = Integer.valueOf(mTileValues[next]);
// Skip outdoor mode if it's unsupported, and skip the day setting
// if it's the same as the off setting
if (((!mConfig.hasFeature(MODE_OUTDOOR) ||
mConfig.hasFeature(FEATURE_MANAGED_OUTDOOR_MODE)
&& nextMode == MODE_OUTDOOR)) ||
(mCTC.getDayColorTemperature() == mConfig.getDefaultDayTemperature()
&& nextMode == MODE_DAY)) {
next++;
if (next >= mTileValues.length) {
next = 0;
}
} else {
break;
}
}
return nextMode;
}
private void publishCustomTile() {
// This action should be performed as system
final int userId = UserHandle.myUserId();
long token = Binder.clearCallingIdentity();
try {
int idx = getCurrentModeIndex();
final UserHandle user = new UserHandle(userId);
final Context resourceContext = QSUtils.getQSTileContext(mContext, userId);
CMStatusBarManager statusBarManager = CMStatusBarManager.getInstance(mContext);
CustomTile tile = new CustomTile.Builder(resourceContext)
.setLabel(mTileEntries[idx])
.setContentDescription(mTileDescriptionEntries[idx])
.setIcon(mTileEntryIconRes[idx])
.setOnLongClickIntent(getCustomTileLongClickPendingIntent())
.setOnClickIntent(getCustomTileNextModePendingIntent())
.shouldCollapsePanel(false)
.build();
statusBarManager.publishTileAsUser(QSConstants.TILE_LIVE_DISPLAY,
LiveDisplayService.class.hashCode(), tile, user);
} finally {
Binder.restoreCallingIdentity(token);
}
}
private void unpublishCustomTile() {
// This action should be performed as system
final int userId = UserHandle.myUserId();
long token = Binder.clearCallingIdentity();
try {
CMStatusBarManager statusBarManager = CMStatusBarManager.getInstance(mContext);
statusBarManager.removeTileAsUser(QSConstants.TILE_LIVE_DISPLAY,
LiveDisplayService.class.hashCode(), new UserHandle(userId));
} finally {
Binder.restoreCallingIdentity(token);
}
}
private PendingIntent getCustomTileNextModePendingIntent() {
Intent i = new Intent(ACTION_NEXT_MODE);
i.putExtra(EXTRA_NEXT_MODE, getNextModeIndex());
return PendingIntent.getBroadcastAsUser(mContext, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.CURRENT);
}
private PendingIntent getCustomTileLongClickPendingIntent() {
Intent i = new Intent(CMSettings.ACTION_LIVEDISPLAY_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return PendingIntent.getActivityAsUser(mContext, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
}
private final BroadcastReceiver mNextModeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int mode = intent.getIntExtra(EXTRA_NEXT_MODE, mConfig.getDefaultMode());
if (mConfig.hasFeature(mode) && mode >= MODE_FIRST && mode <= MODE_LAST) {
putInt(CMSettings.System.DISPLAY_TEMPERATURE_MODE, mode);
}
}
};
private final IBinder mBinder = new ILiveDisplayService.Stub() {
@Override
@ -354,6 +497,7 @@ public class LiveDisplayService extends SystemService {
@Override
protected void update() {
mHandler.obtainMessage(MSG_MODE_CHANGED, getMode(), 0).sendToTarget();
publishCustomTile();
}
int getMode() {

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2015 The CyanogenMod 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M19,5v14H5V5H19
M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z
M10.7,13.3h2.6L12,9.2L10.7,13.3z
M14.6,17l-0.8-2.2h-3.6L9.4,17H7.3l3.6-10h2.2l3.6,10H14.6z" />
</vector>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2015 The CyanogenMod 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M19,5v14H5V5H19
M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z
M14,12c0,1.1-0.9,2-2,2s-2-0.9-2-2s0.9-2,2-2S14,10.9,14,12z
M16,13.7l1.7-1.7L16,10.3V8h-2.3L12,6.3L10.3,8H8v2.3L6.3,12L8,13.7
V16h2.3l1.7,1.7l1.7-1.7H16V13.7z" />
</vector>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2015 The CyanogenMod 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M15.5,15.5c0.4-0.4,0.7-0.8,0.9-1.2c-1.9,1-4.3,0.7-5.8-0.9s-1.9-4-0.9-5.8C9.2,7.8,8.8,8.1,8.5,8.5
c-2,2-2,5.1,0,7.1S13.6,17.5,15.5,15.5z M19,5v14H5V5H19
M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5
C21,3.9,20.1,3,19,3L19,3z" />
</vector>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2015 The CyanogenMod 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M2.7,2.7L1.3,4.1L3,5.8V19c0,1.1,0.9,2,2,2h13.2l1.7,1.7l1.4-1.4L2.7,2.7z
M5,19V7.8l2.8,2.8L6.3,12L8,13.7 V16h2.3l1.7,1.7l1.4-1.4l2.8,2.8H5z
M7.8,5l-2-2H19c1.1,0,2,0.9,2,2v13.2l-2-2V5H7.8z
M16,8v2.3l1.7,1.7l-1.4,1.4l-5.7-5.7L12,6.3 L13.7,8H16z" />
</vector>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2015 The CyanogenMod 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z
M19,19H5V5h14V19z M14,12.3l-2.8,3.5l-2-2.4L6.5,17h11L14,12.3z" />
</vector>

View File

@ -60,4 +60,32 @@
<item>1</item>
<item>3</item>
</string-array>
<!-- LiveDisplay drawables -->
<string-array name="live_display_drawables" translatable="false">
<item>@drawable/ic_livedisplay_auto</item>
<item>@drawable/ic_livedisplay_off</item>
<item>@drawable/ic_livedisplay_day</item>
<item>@drawable/ic_livedisplay_night</item>
<item>@drawable/ic_livedisplay_outdoor</item>
</string-array>
<!-- LiveDisplay description-->
<string-array name="live_display_description" translatable="false">
<item>@string/accessibility_quick_settings_live_display_auto</item>
<item>@string/accessibility_quick_settings_live_display_off</item>
<item>@string/accessibility_quick_settings_live_display_day</item>
<item>@string/accessibility_quick_settings_live_display_night</item>
<item>@string/accessibility_quick_settings_live_display_outdoor</item>
</string-array>
<!-- LiveDisplay announcement-->
<string-array name="live_display_announcement" translatable="false">
<item>@string/accessibility_quick_settings_live_display_changed_auto</item>
<item>@string/accessibility_quick_settings_live_display_changed_off</item>
<item>@string/accessibility_quick_settings_live_display_changed_day</item>
<item>@string/accessibility_quick_settings_live_display_changed_night</item>
<item>@string/accessibility_quick_settings_live_display_changed_outdoor</item>
</string-array>
</resources>

View File

@ -121,6 +121,17 @@
<string name="live_display_outdoor_summary">Use outdoor settings only</string>
<string name="live_display_hint">LiveDisplay can help reduce eyestrain and help you sleep at night. Click here to try it out!</string>
<string name="accessibility_quick_settings_live_display_off">LiveDisplay off.</string>
<string name="accessibility_quick_settings_live_display_auto">LiveDisplay: auto mode.</string>
<string name="accessibility_quick_settings_live_display_day">LiveDisplay: day mode.</string>
<string name="accessibility_quick_settings_live_display_night">LiveDisplay: night mode.</string>
<string name="accessibility_quick_settings_live_display_outdoor">LiveDisplay: outdoor mode.</string>
<string name="accessibility_quick_settings_live_display_changed_off">LiveDisplay turned off.</string>
<string name="accessibility_quick_settings_live_display_changed_auto">LiveDisplay changed to auto mode.</string>
<string name="accessibility_quick_settings_live_display_changed_day">LiveDisplay changed to day mode.</string>
<string name="accessibility_quick_settings_live_display_changed_night">LiveDisplay changed to night mode.</string>
<string name="accessibility_quick_settings_live_display_changed_outdoor">LiveDisplay changed to outdoor mode.</string>
<!-- Third party keyguard permission label -->
<string name="permlab_thirdPartyKeyguard">third party lock screen</string>
<!-- Third party keyguard permission description -->

View File

@ -63,6 +63,9 @@
<java-symbol type="string" name="live_display_outdoor_summary" />
<java-symbol type="drawable" name="ic_livedisplay_notif" />
<java-symbol type="array" name="live_display_announcement" />
<java-symbol type="array" name="live_display_description" />
<java-symbol type="array" name="live_display_drawables" />
<java-symbol type="array" name="live_display_entries" />
<java-symbol type="array" name="live_display_summaries" />
<java-symbol type="array" name="live_display_values" />