cmsdk: Add QS utility classes.
Change-Id: I5644f6d9769614d72220ee68a08202e6c69037d9
This commit is contained in:
parent
fc97734c06
commit
af4d676a93
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue