cmsdk: Add QS utility classes.

Change-Id: I5644f6d9769614d72220ee68a08202e6c69037d9
This commit is contained in:
Adnan Begovic 2015-12-08 14:25:47 -08:00 committed by Danesh M
parent fc97734c06
commit af4d676a93
4 changed files with 431 additions and 0 deletions

View File

@ -63,4 +63,7 @@
<!-- Does the device have multiple LEDs ?
Used to decide if the user can change the multiple LEDs settings -->
<bool name="config_multipleNotificationLeds">false</bool>
<!-- Default, comma-delimited, quick settings tiles. See QSConstants.java for a list of all available tiles -->
<string name="config_defaultQuickSettingsTiles">wifi,bt,cell,airplane,rotation,flashlight,location,edit,cast,visualizer,hotspot,inversion,dnd,live_display</string>
</resources>

View File

@ -73,4 +73,7 @@
<!-- Notification and battery light -->
<java-symbol type="bool" name="config_adjustableNotificationLedBrightness" />
<java-symbol type="bool" name="config_multipleNotificationLeds" />
<!-- Quick Settings tile defaults -->
<java-symbol type="string" name="config_defaultQuickSettingsTiles" />
</resources>

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2015 The CyanogenMod 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 org.cyanogenmod.internal.util;
import java.util.ArrayList;
public class QSConstants {
private QSConstants() {}
public static final String TILE_WIFI = "wifi";
public static final String TILE_BLUETOOTH = "bt";
public static final String TILE_INVERSION = "inversion";
public static final String TILE_CELLULAR = "cell";
public static final String TILE_AIRPLANE = "airplane";
public static final String TILE_ROTATION = "rotation";
public static final String TILE_FLASHLIGHT = "flashlight";
public static final String TILE_LOCATION = "location";
public static final String TILE_CAST = "cast";
public static final String TILE_HOTSPOT = "hotspot";
public static final String TILE_NOTIFICATIONS = "notifications";
public static final String TILE_DATA = "data";
public static final String TILE_ROAMING = "roaming";
public static final String TILE_DDS = "dds";
public static final String TILE_APN = "apn";
public static final String TILE_PROFILES = "profiles";
public static final String TILE_PERFORMANCE = "performance";
public static final String TILE_ADB_NETWORK = "adb_network";
public static final String TILE_NFC = "nfc";
public static final String TILE_COMPASS = "compass";
public static final String TILE_LOCKSCREEN = "lockscreen";
public static final String TILE_LTE = "lte";
public static final String TILE_VISUALIZER = "visualizer";
public static final String TILE_VOLUME = "volume_panel";
public static final String TILE_SCREEN_TIMEOUT = "screen_timeout";
public static final String TILE_LIVE_DISPLAY = "live_display";
public static final String TILE_USB_TETHER = "usb_tether";
public static final String TILE_HEADS_UP = "heads_up";
public static final String TILE_AMBIENT_DISPLAY = "ambient_display";
public static final String TILE_SYNC = "sync";
public static final String TILE_BATTERY_SAVER = "battery_saver";
public static final String TILE_EDIT = "edit";
public static final String TILE_DND = "dnd";
public static final String DYNAMIC_TILE_NEXT_ALARM = "next_alarm";
public static final String DYNAMIC_TILE_IME_SELECTOR = "ime_selector";
public static final String DYNAMIC_TILE_SU = "su";
public static final String DYNAMIC_TILE_ADB = "adb";
protected static final ArrayList<String> STATIC_TILES_AVAILABLE = new ArrayList<String>();
protected static final ArrayList<String> DYNAMIC_TILES_AVAILABLE = new ArrayList<String>();
protected static final ArrayList<String> TILES_AVAILABLE = new ArrayList<String>();
static {
STATIC_TILES_AVAILABLE.add(TILE_WIFI);
STATIC_TILES_AVAILABLE.add(TILE_BLUETOOTH);
STATIC_TILES_AVAILABLE.add(TILE_CELLULAR);
STATIC_TILES_AVAILABLE.add(TILE_AIRPLANE);
STATIC_TILES_AVAILABLE.add(TILE_ROTATION);
STATIC_TILES_AVAILABLE.add(TILE_FLASHLIGHT);
STATIC_TILES_AVAILABLE.add(TILE_LOCATION);
STATIC_TILES_AVAILABLE.add(TILE_EDIT);
STATIC_TILES_AVAILABLE.add(TILE_CAST);
STATIC_TILES_AVAILABLE.add(TILE_HOTSPOT);
STATIC_TILES_AVAILABLE.add(TILE_INVERSION);
STATIC_TILES_AVAILABLE.add(TILE_DND);
// STATIC_TILES_AVAILABLE.add(TILE_NOTIFICATIONS);
// STATIC_TILES_AVAILABLE.add(TILE_DATA);
// STATIC_TILES_AVAILABLE.add(TILE_ROAMING);
// STATIC_TILES_AVAILABLE.add(TILE_DDS);
// STATIC_TILES_AVAILABLE.add(TILE_APN);
// STATIC_TILES_AVAILABLE.add(TILE_PROFILES);
// STATIC_TILES_AVAILABLE.add(TILE_PERFORMANCE);
STATIC_TILES_AVAILABLE.add(TILE_ADB_NETWORK);
// STATIC_TILES_AVAILABLE.add(TILE_NFC);
// STATIC_TILES_AVAILABLE.add(TILE_COMPASS);
// STATIC_TILES_AVAILABLE.add(TILE_LOCKSCREEN);
// STATIC_TILES_AVAILABLE.add(TILE_LTE);
// STATIC_TILES_AVAILABLE.add(TILE_VISUALIZER);
// STATIC_TILES_AVAILABLE.add(TILE_VOLUME);
// STATIC_TILES_AVAILABLE.add(TILE_SCREEN_TIMEOUT);
// STATIC_TILES_AVAILABLE.add(TILE_LIVE_DISPLAY);
// STATIC_TILES_AVAILABLE.add(TILE_USB_TETHER);
// STATIC_TILES_AVAILABLE.add(TILE_HEADS_UP);
// STATIC_TILES_AVAILABLE.add(TILE_AMBIENT_DISPLAY);
// STATIC_TILES_AVAILABLE.add(TILE_SYNC);
// STATIC_TILES_AVAILABLE.add(TILE_BATTERY_SAVER);
// DYNAMIC_TILES_AVAILABLE.add(DYNAMIC_TILE_NEXT_ALARM);
// DYNAMIC_TILES_AVAILABLE.add(DYNAMIC_TILE_IME_SELECTOR);
// DYNAMIC_TILES_AVAILABLE.add(DYNAMIC_TILE_SU);
// DYNAMIC_TILES_AVAILABLE.add(DYNAMIC_TILE_ADB);
TILES_AVAILABLE.addAll(STATIC_TILES_AVAILABLE);
TILES_AVAILABLE.addAll(DYNAMIC_TILES_AVAILABLE);
}
}

View File

@ -0,0 +1,315 @@
/*
* Copyright (C) 2015 The CyanogenMod 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 org.cyanogenmod.internal.util;
import android.bluetooth.BluetoothAdapter;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.SparseArray;
import com.android.internal.telephony.PhoneConstants;
import cyanogenmod.power.PerformanceManager;
import cyanogenmod.providers.CMSettings;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
public class QSUtils {
private static boolean sAvailableTilesFiltered;
private static final SparseArray<Context> sSystemUiContextForUser = new SparseArray<>();
public interface OnQSChanged {
void onQSChanged();
}
private QSUtils() {}
public static boolean isStaticQsTile(String tileSpec) {
return QSConstants.STATIC_TILES_AVAILABLE.contains(tileSpec);
}
public static boolean isDynamicQsTile(String tileSpec) {
return QSConstants.DYNAMIC_TILES_AVAILABLE.contains(tileSpec);
}
public static List<String> getAvailableTiles(Context context) {
filterTiles(context);
return QSConstants.TILES_AVAILABLE;
}
public static List<String> getDefaultTiles(Context context) {
final List<String> tiles = new ArrayList<>();
final String defaults = context.getString(
org.cyanogenmod.platform.internal.R.string.config_defaultQuickSettingsTiles);
if (!TextUtils.isEmpty(defaults)) {
final String[] array = TextUtils.split(defaults, Pattern.quote(","));
for (String item : array) {
if (TextUtils.isEmpty(item)) {
continue;
}
tiles.add(item);
}
filterTiles(context, tiles);
}
return tiles;
}
public static String getDefaultTilesAsString(Context context) {
List<String> list = getDefaultTiles(context);
return TextUtils.join(",", list);
}
private static void filterTiles(Context context, List<String> tiles) {
boolean deviceSupportsMobile = deviceSupportsMobileData(context);
// Tiles that need conditional filtering
Iterator<String> iterator = tiles.iterator();
while (iterator.hasNext()) {
String tileKey = iterator.next();
boolean removeTile = false;
switch (tileKey) {
case QSConstants.TILE_CELLULAR:
case QSConstants.TILE_HOTSPOT:
case QSConstants.TILE_DATA:
case QSConstants.TILE_ROAMING:
case QSConstants.TILE_APN:
removeTile = !deviceSupportsMobile;
break;
case QSConstants.TILE_DDS:
removeTile = !deviceSupportsDdsSupported(context);
break;
case QSConstants.TILE_FLASHLIGHT:
removeTile = !deviceSupportsFlashLight(context);
break;
case QSConstants.TILE_BLUETOOTH:
removeTile = !deviceSupportsBluetooth();
break;
case QSConstants.TILE_NFC:
removeTile = !deviceSupportsNfc(context);
break;
case QSConstants.TILE_COMPASS:
removeTile = !deviceSupportsCompass(context);
break;
case QSConstants.TILE_AMBIENT_DISPLAY:
removeTile = !deviceSupportsDoze(context);
break;
case QSConstants.TILE_PERFORMANCE:
removeTile = !deviceSupportsPowerProfiles(context);
break;
case QSConstants.TILE_BATTERY_SAVER:
removeTile = deviceSupportsPowerProfiles(context);
break;
case QSConstants.DYNAMIC_TILE_SU:
removeTile = !supportsRootAccess();
break;
}
if (removeTile) {
iterator.remove();
}
}
}
private static void filterTiles(Context context) {
if (!sAvailableTilesFiltered) {
filterTiles(context, QSConstants.TILES_AVAILABLE);
sAvailableTilesFiltered = true;
}
}
public static int getDynamicQSTileResIconId(Context context, int userId, String tileSpec) {
Context ctx = getQSTileContext(context, userId);
int index = translateDynamicQsTileSpecToIndex(ctx, tileSpec);
if (index == -1) {
return 0;
}
try {
String resourceName = ctx.getResources().getStringArray(
ctx.getResources().getIdentifier("dynamic_qs_tiles_icons_resources_ids",
"array", ctx.getPackageName()))[index];
return ctx.getResources().getIdentifier(
resourceName, "drawable", ctx.getPackageName());
} catch (Exception ex) {
// Ignore
}
return 0;
}
public static String getDynamicQSTileLabel(Context context, int userId, String tileSpec) {
Context ctx = getQSTileContext(context, userId);
int index = translateDynamicQsTileSpecToIndex(ctx, tileSpec);
if (index == -1) {
return null;
}
try {
return ctx.getResources().getStringArray(
ctx.getResources().getIdentifier("dynamic_qs_tiles_labels",
"array", ctx.getPackageName()))[index];
} catch (Exception ex) {
// Ignore
}
return null;
}
private static int translateDynamicQsTileSpecToIndex(Context context, String tileSpec) {
String[] keys = context.getResources().getStringArray(context.getResources().getIdentifier(
"dynamic_qs_tiles_values", "array", context.getPackageName()));
int count = keys.length;
for (int i = 0; i < count; i++) {
if (keys[i].equals(tileSpec)) {
return i;
}
}
return -1;
}
public static Context getQSTileContext(Context context, int userId) {
Context ctx = sSystemUiContextForUser.get(userId);
if (ctx == null) {
try {
ctx = context.createPackageContextAsUser(
"com.android.systemui", 0, new UserHandle(userId));
sSystemUiContextForUser.put(userId, ctx);
} catch (NameNotFoundException ex) {
// We can safely ignore this
}
}
return ctx;
}
public static boolean isQSTileEnabledForUser(
Context context, String tileSpec, int userId) {
final ContentResolver resolver = context.getContentResolver();
String order = CMSettings.Secure.getStringForUser(resolver,
CMSettings.Secure.QS_TILES, userId);
return !TextUtils.isEmpty(order) && Arrays.asList(order.split(",")).contains(tileSpec);
}
public static ContentObserver registerObserverForQSChanges(Context ctx, final OnQSChanged cb) {
ContentObserver observer = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange, Uri uri) {
cb.onQSChanged();
}
};
ctx.getContentResolver().registerContentObserver(
CMSettings.Secure.getUriFor(CMSettings.Secure.QS_TILES),
false, observer, UserHandle.USER_ALL);
return observer;
}
public static void unregisterObserverForQSChanges(Context ctx, ContentObserver observer) {
ctx.getContentResolver().unregisterContentObserver(observer);
}
public static boolean deviceSupportsLte(Context ctx) {
final TelephonyManager tm = (TelephonyManager)
ctx.getSystemService(Context.TELEPHONY_SERVICE);
return (tm.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE)
|| tm.getLteOnGsmMode() != 0;
}
public static boolean deviceSupportsDdsSupported(Context context) {
TelephonyManager tm = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.isMultiSimEnabled()
&& tm.getMultiSimConfiguration() == TelephonyManager.MultiSimVariants.DSDA;
}
public static boolean deviceSupportsMobileData(Context ctx) {
ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(
Context.CONNECTIVITY_SERVICE);
return cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
}
public static boolean deviceSupportsBluetooth() {
return BluetoothAdapter.getDefaultAdapter() != null;
}
public static boolean deviceSupportsNfc(Context context) {
PackageManager packageManager = context.getPackageManager();
return packageManager.hasSystemFeature(PackageManager.FEATURE_NFC);
}
public static boolean deviceSupportsFlashLight(Context context) {
CameraManager cameraManager = (CameraManager) context.getSystemService(
Context.CAMERA_SERVICE);
try {
String[] ids = cameraManager.getCameraIdList();
for (String id : ids) {
CameraCharacteristics c = cameraManager.getCameraCharacteristics(id);
Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
if (flashAvailable != null
&& flashAvailable
&& lensFacing != null
&& lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
return true;
}
}
} catch (CameraAccessException | AssertionError e) {
// Ignore
}
return false;
}
public static boolean deviceSupportsCompass(Context context) {
SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
return sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null
&& sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null;
}
public static boolean deviceSupportsDoze(Context context) {
String name = context.getResources().getString(
com.android.internal.R.string.config_dozeComponent);
return !TextUtils.isEmpty(name);
}
public static boolean deviceSupportsPowerProfiles(Context context) {
PerformanceManager pm = PerformanceManager.getInstance(context);
return pm.getNumberOfProfiles() > 0;
}
private static boolean supportsRootAccess() {
return Build.IS_DEBUGGABLE || "eng".equals(Build.TYPE);
}
}