diff --git a/Android.bp b/Android.bp index 22fe23dc85ee..c7b2f5cd3ed8 100644 --- a/Android.bp +++ b/Android.bp @@ -247,6 +247,8 @@ java_library { "core/java/android/os/storage/IStorageEventListener.aidl", "core/java/android/os/storage/IStorageShutdownObserver.aidl", "core/java/android/os/storage/IObbActionListener.aidl", + "core/java/android/pocket/IPocketService.aidl", + "core/java/android/pocket/IPocketCallback.aidl", ":keystore_aidl", "core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl", "core/java/android/service/autofill/IAutoFillService.aidl", @@ -271,6 +273,7 @@ java_library { "core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl", "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl", "core/java/android/service/gatekeeper/IGateKeeperService.aidl", + "core/java/android/service/gesture/IGestureService.aidl", "core/java/android/service/notification/INotificationListener.aidl", "core/java/android/service/notification/IStatusBarNotificationHolder.aidl", "core/java/android/service/notification/IConditionListener.aidl", @@ -584,6 +587,8 @@ java_library { "packages/services/Proxy/com/android/net/IProxyPortListener.aidl", "core/java/android/service/quicksettings/IQSService.aidl", "core/java/android/service/quicksettings/IQSTileService.aidl", + "telephony/java/com/android/internal/telephony/ISmsSecurityService.aidl", + "telephony/java/com/android/internal/telephony/ISmsSecurityAgent.aidl", ":libupdate_engine_aidl", @@ -730,22 +735,24 @@ gensrcs { name: "framework-javastream-protos", depfile: true, + tool_files: [ "tools/genprotos.sh", ], tools: [ "aprotoc", "protoc-gen-javastream", "soong_zip", ], - cmd: "mkdir -p $(genDir)/$(in) " + - "&& $(location aprotoc) " + - " --plugin=$(location protoc-gen-javastream) " + - " --dependency_out=$(depfile) " + - " --javastream_out=$(genDir)/$(in) " + - " -Iexternal/protobuf/src " + - " -I . " + - " $(in) " + - "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)", - + // TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can + // end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to + // the way sbox rewrites the command. See b/70221552. + cmd: "$(location tools/genprotos.sh) " + + " $(location aprotoc) " + + " $(location protoc-gen-javastream) " + + " $(location soong_zip) " + + " $(genDir) " + + " $(depfile) " + + " $(in) " + + " $(out)", srcs: [ "core/proto/**/*.proto", "libs/incident/**/*.proto", diff --git a/CleanSpec.mk b/CleanSpec.mk index 2e949c5c05a9..f2a75884f4a2 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -78,6 +78,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/symbols/system/lib/libhwui.so) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libhwui.so) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/storage/*) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/IClipboard.P) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/pocket/*) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/android/internal/telephony/ITelephonyRegistry.P) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/docs/api-stubs*) diff --git a/api/current.txt b/api/current.txt index 557d5365a92c..a6ddc854b124 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28133,7 +28133,7 @@ package android.net.wifi { method public int addNetwork(android.net.wifi.WifiConfiguration); method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration); method public static int calculateSignalLevel(int, int); - method public deprecated void cancelWps(android.net.wifi.WifiManager.WpsCallback); + method public void cancelWps(android.net.wifi.WifiManager.WpsCallback); method public static int compareSignalLevel(int, int); method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String); method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String); @@ -28166,7 +28166,7 @@ package android.net.wifi { method public boolean setWifiEnabled(boolean); method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler); method public deprecated boolean startScan(); - method public deprecated void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback); + method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback); method public int updateNetwork(android.net.wifi.WifiConfiguration); field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE"; @@ -28196,11 +28196,11 @@ package android.net.wifi { field public static final int WIFI_STATE_ENABLED = 3; // 0x3 field public static final int WIFI_STATE_ENABLING = 2; // 0x2 field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4 - field public static final deprecated int WPS_AUTH_FAILURE = 6; // 0x6 - field public static final deprecated int WPS_OVERLAP_ERROR = 3; // 0x3 - field public static final deprecated int WPS_TIMED_OUT = 7; // 0x7 - field public static final deprecated int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5 - field public static final deprecated int WPS_WEP_PROHIBITED = 4; // 0x4 + field public static final int WPS_AUTH_FAILURE = 6; // 0x6 + field public static final int WPS_OVERLAP_ERROR = 3; // 0x3 + field public static final int WPS_TIMED_OUT = 7; // 0x7 + field public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5 + field public static final int WPS_WEP_PROHIBITED = 4; // 0x4 } public static class WifiManager.LocalOnlyHotspotCallback { @@ -28234,28 +28234,27 @@ package android.net.wifi { method public void setWorkSource(android.os.WorkSource); } - public static abstract deprecated class WifiManager.WpsCallback { + public static abstract class WifiManager.WpsCallback { ctor public WifiManager.WpsCallback(); - method public abstract deprecated void onFailed(int); - method public abstract deprecated void onStarted(java.lang.String); - method public abstract deprecated void onSucceeded(); + method public abstract void onFailed(int); + method public abstract void onStarted(java.lang.String); + method public abstract void onSucceeded(); } - public deprecated class WpsInfo implements android.os.Parcelable { - ctor public deprecated WpsInfo(); - ctor public deprecated WpsInfo(android.net.wifi.WpsInfo); - method public deprecated int describeContents(); - method public deprecated java.lang.String toString(); - method public deprecated void writeToParcel(android.os.Parcel, int); - field public deprecated java.lang.String BSSID; - field public static final deprecated android.os.Parcelable.Creator CREATOR; - field public static final deprecated int DISPLAY = 1; // 0x1 - field public static final deprecated int INVALID = 4; // 0x4 - field public static final deprecated int KEYPAD = 2; // 0x2 - field public static final deprecated int LABEL = 3; // 0x3 - field public static final deprecated int PBC = 0; // 0x0 - field public deprecated java.lang.String pin; - field public deprecated int setup; + public class WpsInfo implements android.os.Parcelable { + ctor public WpsInfo(); + ctor public WpsInfo(android.net.wifi.WpsInfo); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public java.lang.String BSSID; + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int DISPLAY = 1; // 0x1 + field public static final int INVALID = 4; // 0x4 + field public static final int KEYPAD = 2; // 0x2 + field public static final int LABEL = 3; // 0x3 + field public static final int PBC = 0; // 0x0 + field public java.lang.String pin; + field public int setup; } } @@ -36779,6 +36778,7 @@ package android.provider { field public static final android.net.Uri DEFAULT_ALARM_ALERT_URI; field public static final android.net.Uri DEFAULT_NOTIFICATION_URI; field public static final android.net.Uri DEFAULT_RINGTONE_URI; + field public static final android.net.Uri DEFAULT_RINGTONE2_URI; field public static final deprecated java.lang.String DEVICE_PROVISIONED = "device_provisioned"; field public static final deprecated java.lang.String DIM_SCREEN = "dim_screen"; field public static final java.lang.String DTMF_TONE_TYPE_WHEN_DIALING = "dtmf_tone_type"; @@ -36807,6 +36807,7 @@ package android.provider { field public static final deprecated java.lang.String RADIO_NFC = "nfc"; field public static final deprecated java.lang.String RADIO_WIFI = "wifi"; field public static final java.lang.String RINGTONE = "ringtone"; + field public static final java.lang.String RINGTONE2 = "ringtone2"; field public static final java.lang.String SCREEN_BRIGHTNESS = "screen_brightness"; field public static final java.lang.String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode"; field public static final int SCREEN_BRIGHTNESS_MODE_AUTOMATIC = 1; // 0x1 diff --git a/api/system-current.txt b/api/system-current.txt index 3b4a0be6cd13..3a32eca57fd0 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5487,6 +5487,7 @@ package android.telephony.ims { method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo); method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile); method public void callSessionResumed(android.telephony.ims.ImsCallProfile); + method public void callSessionPropertyChanged(int); method public void callSessionRttMessageReceived(java.lang.String); method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile); method public void callSessionRttModifyResponseReceived(int); @@ -6077,6 +6078,7 @@ package android.telephony.ims.stub { public class ImsUtImplBase { ctor public ImsUtImplBase(); method public void close(); + method public int queryCFForServiceClass(int, java.lang.String, int); method public int queryCallBarring(int); method public int queryCallBarringForServiceClass(int, int); method public int queryCallForward(int, java.lang.String); diff --git a/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp b/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp index 0615c74b8d64..2a89c920c119 100644 --- a/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp +++ b/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp @@ -75,18 +75,13 @@ PageTypeInfoParser::Parse(const int in, const int out) const } else return BAD_VALUE; // expect part 2 starts with "type" if (stripPrefix(&record[2], "type")) { - // expect the rest of part 2 has number of (pageBlockOrder + 2) parts // An example looks like: // header line: type 0 1 2 3 4 5 6 7 8 9 10 // record line: Unmovable 426 279 226 1 1 1 0 0 2 2 0 - // The pageBlockOrder = 10 and it's zero-indexed. so total parts - // are 10 + 1(zero-indexed) + 1(the type part) = 12. record_t pageCounts = parseRecord(record[2]); - int pageCountsSize = pageBlockOrder + 2; - if ((int)pageCounts.size() != pageCountsSize) return BAD_VALUE; proto.write(PageTypeInfoProto::MigrateType::TYPE, pageCounts[0]); - for (auto i=1; iname.string(), proto.size()); return NO_ERROR; -} \ No newline at end of file +} diff --git a/cmds/incident_helper/testdata/pagetypeinfo.txt b/cmds/incident_helper/testdata/pagetypeinfo.txt index d45ddc408c0f..c65b5a1fa1e1 100644 --- a/cmds/incident_helper/testdata/pagetypeinfo.txt +++ b/cmds/incident_helper/testdata/pagetypeinfo.txt @@ -1,5 +1,5 @@ -Page block order: 10 -Pages per block: 1024 +Page block order: 9 +Pages per block: 512 Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10 Node 0, zone DMA, type Unmovable 426 279 226 1 1 1 0 0 2 2 0 diff --git a/cmds/incident_helper/tests/PageTypeInfoParser_test.cpp b/cmds/incident_helper/tests/PageTypeInfoParser_test.cpp index 9bad7be4a07e..5688681e45fd 100644 --- a/cmds/incident_helper/tests/PageTypeInfoParser_test.cpp +++ b/cmds/incident_helper/tests/PageTypeInfoParser_test.cpp @@ -54,8 +54,8 @@ TEST_F(PageTypeInfoParserTest, Success) { PageTypeInfoParser parser; PageTypeInfoProto expected; - expected.set_page_block_order(10); - expected.set_pages_per_block(1024); + expected.set_page_block_order(9); + expected.set_pages_per_block(512); PageTypeInfoProto::MigrateType* mt1 = expected.add_migrate_types(); mt1->set_node(0); diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java index d3ec32076292..db518ff4b8b4 100644 --- a/cmds/input/src/com/android/commands/input/Input.java +++ b/cmds/input/src/com/android/commands/input/Input.java @@ -48,6 +48,7 @@ public class Input { put("touchpad", InputDevice.SOURCE_TOUCHPAD); put("touchnavigation", InputDevice.SOURCE_TOUCH_NAVIGATION); put("joystick", InputDevice.SOURCE_JOYSTICK); + put("gesture", InputDevice.SOURCE_GESTURE_SENSOR); }}; diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 764366fc420a..087009e4b0f7 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -352,6 +352,10 @@ void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) { ALOGW("not interested in atom %d", atomId); return; } + if (atomId < 0) { + android_errorWriteLog(0x534e4554, "187957589"); + return; + } mPushedAtomStats[atomId]++; } diff --git a/config/hiddenapi-private-dex.txt b/config/hiddenapi-private-dex.txt index c3cf29a7a7b2..c874687e3b51 100644 --- a/config/hiddenapi-private-dex.txt +++ b/config/hiddenapi-private-dex.txt @@ -4421,9 +4421,9 @@ Landroid/app/AppOpsManager$OnOpChangedInternalListener; Landroid/app/AppOpsManager$OnOpChangedInternalListener;->()V Landroid/app/AppOpsManager$OnOpChangedInternalListener;->onOpChanged(ILjava/lang/String;)V Landroid/app/AppOpsManager$OpEntry; -Landroid/app/AppOpsManager$OpEntry;->(IIJJIILjava/lang/String;)V -Landroid/app/AppOpsManager$OpEntry;->(II[J[JIILjava/lang/String;)V -Landroid/app/AppOpsManager$OpEntry;->(II[J[JIZILjava/lang/String;)V +Landroid/app/AppOpsManager$OpEntry;->(IIJJIILjava/lang/String;II)V +Landroid/app/AppOpsManager$OpEntry;->(II[J[JIILjava/lang/String;II)V +Landroid/app/AppOpsManager$OpEntry;->(II[J[JIZILjava/lang/String;II)V Landroid/app/AppOpsManager$OpEntry;->(Landroid/os/Parcel;)V Landroid/app/AppOpsManager$OpEntry;->CREATOR:Landroid/os/Parcelable$Creator; Landroid/app/AppOpsManager$OpEntry;->getDuration()I @@ -70328,6 +70328,7 @@ Landroid/provider/Settings$Secure;->VOICE_RECOGNITION_SERVICE:Ljava/lang/String; Landroid/provider/Settings$Secure;->VOLUME_HUSH_GESTURE:Ljava/lang/String; Landroid/provider/Settings$Secure;->VOLUME_HUSH_GESTURE_VALIDATOR:Landroid/provider/SettingsValidators$Validator; Landroid/provider/Settings$Secure;->VOLUME_HUSH_MUTE:I +Landroid/provider/Settings$Secure;->VOLUME_HUSH_MUTE_NO_MEDIA:I Landroid/provider/Settings$Secure;->VOLUME_HUSH_OFF:I Landroid/provider/Settings$Secure;->VOLUME_HUSH_VIBRATE:I Landroid/provider/Settings$Secure;->VR_DISPLAY_MODE:Ljava/lang/String; @@ -113337,6 +113338,7 @@ Lcom/android/internal/R$bool;->config_sustainedPerformanceModeSupported:I Lcom/android/internal/R$bool;->config_swipeDisambiguation:I Lcom/android/internal/R$bool;->config_swipe_up_gesture_default:I Lcom/android/internal/R$bool;->config_swipe_up_gesture_setting_available:I +Lcom/android/internal/R$bool;->config_custom_swipe_up_gesture_setting_available:I Lcom/android/internal/R$bool;->config_switch_phone_on_voice_reg_state_change:I Lcom/android/internal/R$bool;->config_syncstorageengine_masterSyncAutomatically:I Lcom/android/internal/R$bool;->config_timeZoneRulesUpdateTrackingEnabled:I @@ -115404,6 +115406,7 @@ Lcom/android/internal/R$string;->default_browser:I Lcom/android/internal/R$string;->default_notification_channel_label:I Lcom/android/internal/R$string;->default_sms_application:I Lcom/android/internal/R$string;->default_wallpaper_component:I +Lcom/android/internal/R$string;->default_wallpaper_component_custom:I Lcom/android/internal/R$string;->delete:I Lcom/android/internal/R$string;->deleted_key:I Lcom/android/internal/R$string;->deleteText:I @@ -116212,6 +116215,7 @@ Lcom/android/internal/R$string;->view_flight:I Lcom/android/internal/R$string;->view_flight_desc:I Lcom/android/internal/R$string;->volume_alarm:I Lcom/android/internal/R$string;->volume_dialog_ringer_guidance_silent:I +Lcom/android/internal/R$string;->volume_dialog_ringer_guidance_silent_no_media:I Lcom/android/internal/R$string;->volume_dialog_ringer_guidance_vibrate:I Lcom/android/internal/R$string;->volume_icon_description_bluetooth:I Lcom/android/internal/R$string;->volume_icon_description_incall:I diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java index b6e85f18a695..3f90f36fb2a1 100644 --- a/core/java/android/accounts/Account.java +++ b/core/java/android/accounts/Account.java @@ -88,6 +88,12 @@ public Account(String name, String type, String accessId) { public Account(Parcel in) { this.name = in.readString(); this.type = in.readString(); + if (TextUtils.isEmpty(name)) { + throw new android.os.BadParcelableException("the name must not be empty: " + name); + } + if (TextUtils.isEmpty(type)) { + throw new android.os.BadParcelableException("the type must not be empty: " + type); + } this.accessId = in.readString(); if (accessId != null) { synchronized (sAccessedAccounts) { diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 5176d71ea67b..6b3d2c5a94d1 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -479,6 +479,7 @@ public static AccountManager get(Context context) { * @return The account's password, null if none or if the account doesn't exist */ public String getPassword(final Account account) { + android.util.SeempLog.record(22); if (account == null) throw new IllegalArgumentException("account is null"); try { return mService.getPassword(account); @@ -509,6 +510,7 @@ public String getPassword(final Account account) { * @return The user data, null if the account or key doesn't exist */ public String getUserData(final Account account, final String key) { + android.util.SeempLog.record(23); if (account == null) throw new IllegalArgumentException("account is null"); if (key == null) throw new IllegalArgumentException("key is null"); try { @@ -730,6 +732,7 @@ public AccountManagerFuture getAuthTokenLabel( return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.getAuthTokenLabel(mResponse, accountType, authTokenType); } @@ -774,6 +777,7 @@ public AccountManagerFuture hasFeatures(final Account account, return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName()); } @Override @@ -834,6 +838,7 @@ public AccountManagerFuture getAccountsByTypeAndFeatures( return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.getAccountsByFeatures(mResponse, type, features, mContext.getOpPackageName()); } @@ -878,6 +883,7 @@ public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException { * already exists, the account is null, or another error occurs. */ public boolean addAccountExplicitly(Account account, String password, Bundle userdata) { + android.util.SeempLog.record(24); if (account == null) throw new IllegalArgumentException("account is null"); try { return mService.addAccountExplicitly(account, password, userdata); @@ -1095,6 +1101,7 @@ public AccountManagerFuture renameAccount( return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.renameAccount(mResponse, account, newName); } @Override @@ -1155,10 +1162,12 @@ public String getPreviousName(final Account account) { @Deprecated public AccountManagerFuture removeAccount(final Account account, AccountManagerCallback callback, Handler handler) { + android.util.SeempLog.record(25); if (account == null) throw new IllegalArgumentException("account is null"); return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.removeAccount(mResponse, account, false); } @Override @@ -1214,10 +1223,12 @@ public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException { */ public AccountManagerFuture removeAccount(final Account account, final Activity activity, AccountManagerCallback callback, Handler handler) { + android.util.SeempLog.record(28); if (account == null) throw new IllegalArgumentException("account is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(34); mService.removeAccount(mResponse, account, activity != null); } }.start(); @@ -1239,6 +1250,7 @@ public AccountManagerFuture removeAccountAsUser(final Account account, return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier()); } @Override @@ -1265,6 +1277,7 @@ public AccountManagerFuture removeAccountAsUser(final Account account, return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(34); mService.removeAccountAsUser(mResponse, account, activity != null, userHandle.getIdentifier()); } @@ -1378,6 +1391,7 @@ public String peekAuthToken(final Account account, final String authTokenType) { * @param password The password to set, null to clear the password */ public void setPassword(final Account account, final String password) { + android.util.SeempLog.record(26); if (account == null) throw new IllegalArgumentException("account is null"); try { mService.setPassword(account, password); @@ -1406,6 +1420,7 @@ public void setPassword(final Account account, final String password) { * @param account The account whose password to clear */ public void clearPassword(final Account account) { + android.util.SeempLog.record(27); if (account == null) throw new IllegalArgumentException("account is null"); try { mService.clearPassword(account); @@ -1433,6 +1448,7 @@ public void clearPassword(final Account account) { * @param value String value to set, {@code null} to clear this user data key */ public void setUserData(final Account account, final String key, final String value) { + android.util.SeempLog.record(28); if (account == null) throw new IllegalArgumentException("account is null"); if (key == null) throw new IllegalArgumentException("key is null"); try { @@ -1583,6 +1599,7 @@ public AccountManagerFuture getAuthToken( return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.getAuthToken(mResponse, account, authTokenType, false /* notifyOnAuthFailure */, true /* expectActivityLaunch */, optionsIn); @@ -1754,6 +1771,7 @@ public AccountManagerFuture getAuthToken( return new AmsTask(null, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.getAuthToken(mResponse, account, authTokenType, notifyAuthFailure, false /* expectActivityLaunch */, optionsIn); } @@ -1814,6 +1832,7 @@ public AccountManagerFuture addAccount(final String accountType, final String authTokenType, final String[] requiredFeatures, final Bundle addAccountOptions, final Activity activity, AccountManagerCallback callback, Handler handler) { + android.util.SeempLog.record(29); if (accountType == null) throw new IllegalArgumentException("accountType is null"); final Bundle optionsIn = new Bundle(); if (addAccountOptions != null) { @@ -1824,6 +1843,7 @@ public AccountManagerFuture addAccount(final String accountType, return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.addAccount(mResponse, accountType, authTokenType, requiredFeatures, activity != null, optionsIn); } @@ -1849,6 +1869,7 @@ public AccountManagerFuture addAccountAsUser(final String accountType, return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.addAccountAsUser(mResponse, accountType, authTokenType, requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier()); } @@ -1898,6 +1919,7 @@ public AccountManagerFuture copyAccountToUser( return new Future2Task(handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(34); mService.copyAccountToUser( mResponse, account, fromUser.getIdentifier(), toUser.getIdentifier()); } @@ -2024,6 +2046,7 @@ public AccountManagerFuture confirmCredentialsAsUser(final Account accou return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.confirmCredentialsAsUser(mResponse, account, options, activity != null, userId); } @@ -2137,10 +2160,12 @@ public void doWork() throws RemoteException { public AccountManagerFuture editProperties(final String accountType, final Activity activity, final AccountManagerCallback callback, final Handler handler) { + android.util.SeempLog.record(30); if (accountType == null) throw new IllegalArgumentException("accountType is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); mService.editProperties(mResponse, accountType, activity != null); } }.start(); @@ -2561,6 +2586,7 @@ private class GetAuthTokenByTypeAndFeaturesTask @Override public void doWork() throws RemoteException { + android.util.SeempLog.record(31); getAccountByTypeAndFeatures(mAccountType, mFeatures, new AccountManagerCallback() { @Override diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java index 6a436869a0ec..0502087e14d7 100644 --- a/core/java/android/accounts/ChooseAccountActivity.java +++ b/core/java/android/accounts/ChooseAccountActivity.java @@ -24,8 +24,8 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Parcelable; -import android.os.RemoteException; import android.os.Process; +import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; @@ -36,6 +36,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; + import com.android.internal.R; import java.util.HashMap; @@ -59,6 +60,9 @@ public class ChooseAccountActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addPrivateFlags( + android.view.WindowManager.LayoutParams + .PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS); mAccountManagerResponse = getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE); diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java index e3352bc85668..4b998e86fc8a 100644 --- a/core/java/android/accounts/ChooseAccountTypeActivity.java +++ b/core/java/android/accounts/ChooseAccountTypeActivity.java @@ -31,6 +31,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; + import com.android.internal.R; import java.util.ArrayList; @@ -51,7 +52,9 @@ public class ChooseAccountTypeActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + getWindow().addPrivateFlags( + android.view.WindowManager.LayoutParams + .PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState=" + savedInstanceState + ")"); diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java index 6680ce6acb04..887ba18822f8 100644 --- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java +++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java @@ -15,8 +15,6 @@ */ package android.accounts; -import com.google.android.collect.Sets; - import android.app.Activity; import android.app.ActivityManager; import android.content.Intent; @@ -38,6 +36,8 @@ import com.android.internal.R; +import com.google.android.collect.Sets; + import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -142,7 +142,9 @@ public void onCreate(Bundle savedInstanceState) { Log.v(TAG, "ChooseTypeAndAccountActivity.onCreate(savedInstanceState=" + savedInstanceState + ")"); } - + getWindow().addPrivateFlags( + android.view.WindowManager.LayoutParams + .PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); String message = null; try { diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java index af74b036a796..d82776f8e45c 100644 --- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java +++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java @@ -16,16 +16,23 @@ package android.accounts; import android.app.Activity; -import android.content.res.Resources; -import android.os.Bundle; -import android.widget.TextView; -import android.widget.LinearLayout; -import android.view.View; -import android.view.LayoutInflater; +import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + import com.android.internal.R; import java.io.IOException; @@ -42,11 +49,15 @@ public class GrantCredentialsPermissionActivity extends Activity implements View private Account mAccount; private String mAuthTokenType; private int mUid; + private int mCallingUid; private Bundle mResultBundle = null; protected LayoutInflater mInflater; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addPrivateFlags( + android.view.WindowManager.LayoutParams + .PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); setContentView(R.layout.grant_credentials_permission); setTitle(R.string.grant_permissions_header_text); @@ -74,6 +85,20 @@ protected void onCreate(Bundle savedInstanceState) { return; } + try { + IBinder activityToken = getActivityToken(); + mCallingUid = ActivityManager.getService().getLaunchedFromUid(activityToken); + } catch (RemoteException re) { + // Couldn't figure out caller details + Log.w(getClass().getSimpleName(), "Unable to get caller identity \n" + re); + } + + if (!UserHandle.isSameApp(mCallingUid, Process.SYSTEM_UID) && mCallingUid != mUid) { + setResult(Activity.RESULT_CANCELED); + finish(); + return; + } + String accountTypeLabel; try { accountTypeLabel = getAccountLabel(mAccount); diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 14cae95508e7..03fa142af303 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -403,6 +403,21 @@ public interface ScreenObserver { */ public abstract List getMemoryStateForProcesses(); + /** + * Returns {@code true} if the given notification channel currently has a + * notification associated with a foreground service. This is an AMS check + * because that is the source of truth for the FGS state. + */ + public abstract boolean hasForegroundServiceNotification(String pkg, int userId, + String channelId); + + /** + * If the given app has any FGSs whose notifications are in the given channel, + * stop them. + */ + public abstract void stopForegroundServicesForChannel(String pkg, int userId, + String channelId); + /** * This enforces {@code func} can only be called if either the caller is Recents activity or * has {@code permission}. diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 14a622a68fad..db4085a85a2d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3943,13 +3943,14 @@ public void handleResumeActivity(IBinder token, boolean finalStateRequest, boole l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit; - if (r.activity.mVisibleFromClient) { - ViewManager wm = a.getWindowManager(); - View decor = r.window.getDecorView(); - wm.updateViewLayout(decor, l); - } } + if (r.activity.mVisibleFromClient) { + ViewManager wm = a.getWindowManager(); + View decor = r.window.getDecorView(); + wm.updateViewLayout(decor, l); + } + r.activity.mVisibleFromServer = true; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { @@ -6023,7 +6024,7 @@ public final IContentProvider acquireProvider( throw ex.rethrowFromSystemServer(); } if (holder == null) { - Slog.e(TAG, "Failed to find provider info for " + auth); + if (DEBUG_MESSAGES) Slog.e(TAG, "Failed to find provider info for " + auth); return null; } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index c58b91e39d0f..78a1e978e9f7 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 The Android Open Source Project + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,6 +119,12 @@ public class AppOpsManager { */ public static final int MODE_FOREGROUND = 4; + /** + * @hide Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: + * AppOps Service should show a dialog box on screen to get user permission. + */ + public static final int MODE_ASK = 5; + /** * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}: * Also get reports if the foreground state of an op's uid changes. This only works @@ -135,6 +142,7 @@ public class AppOpsManager { "deny", // MODE_ERRORED "default", // MODE_DEFAULT "foreground", // MODE_FOREGROUND + "ask", // MODE_ASK }; /** @@ -188,7 +196,8 @@ public class AppOpsManager { // when adding one of these: // - increment _NUM_OP // - define an OPSTR_* constant (marked as @SystemApi) - // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault + // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault, + // sOpDefaultStrictMode, sOpToOpString, sOpStrictMode. // - add descriptive strings to Settings/res/values/arrays.xml // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) @@ -352,8 +361,16 @@ public class AppOpsManager { public static final int OP_START_FOREGROUND = 76; /** @hide */ public static final int OP_BLUETOOTH_SCAN = 77; + /** @hide Bluetooth state change */ + public static final int OP_BLUETOOTH_CHANGE = 78; + /** @hide Boot completed */ + public static final int OP_BOOT_COMPLETED = 79; + /** @hide NFC state change */ + public static final int OP_NFC_CHANGE = 80; + /** @hide Data connect state change */ + public static final int OP_DATA_CONNECT_CHANGE = 81; /** @hide */ - public static final int _NUM_OP = 78; + public static final int _NUM_OP = 82; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -597,6 +614,14 @@ public class AppOpsManager { public static final String OPSTR_START_FOREGROUND = "android:start_foreground"; /** @hide */ public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan"; + /** @hide */ + public static final String OPSTR_BLUETOOTH_CHANGE = "android:bluetooth_change"; + /** @hide */ + public static final String OPSTR_BOOT_COMPLETED = "android:boot_completed"; + /** @hide */ + public static final String OPSTR_NFC_CHANGE = "android:nfc_change"; + /** @hide */ + public static final String OPSTR_DATA_CONNECT_CHANGE = "android:data_connect_change"; // Warning: If an permission is added here it also has to be added to // com.android.packageinstaller.permission.utils.EventLogger @@ -645,7 +670,7 @@ public class AppOpsManager { OP_SYSTEM_ALERT_WINDOW, OP_WRITE_SETTINGS, OP_REQUEST_INSTALL_PACKAGES, - OP_START_FOREGROUND, + OP_START_FOREGROUND }; /** @@ -667,7 +692,7 @@ public class AppOpsManager { OP_WRITE_CALL_LOG, // WRITE_CALL_LOG OP_READ_CALENDAR, // READ_CALENDAR OP_WRITE_CALENDAR, // WRITE_CALENDAR - OP_COARSE_LOCATION, // WIFI_SCAN + OP_WIFI_SCAN, // WIFI_SCAN OP_POST_NOTIFICATION, // POST_NOTIFICATION OP_COARSE_LOCATION, // NEIGHBORING_CELLS OP_CALL_PHONE, // CALL_PHONE @@ -734,7 +759,11 @@ public class AppOpsManager { OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS OP_START_FOREGROUND, // START_FOREGROUND - OP_COARSE_LOCATION, // BLUETOOTH_SCAN + OP_FINE_LOCATION, // BLUETOOTH_SCAN + OP_BLUETOOTH_CHANGE, // BLUETOOTH_CHANGE + OP_BOOT_COMPLETED, // BOOT_COMPLETED + OP_NFC_CHANGE, // NFC_CHANGE + OP_DATA_CONNECT_CHANGE, // DATA_CONNECT_CHANGE }; /** @@ -819,6 +848,10 @@ public class AppOpsManager { OPSTR_MANAGE_IPSEC_TUNNELS, OPSTR_START_FOREGROUND, OPSTR_BLUETOOTH_SCAN, + OPSTR_BLUETOOTH_CHANGE, + OPSTR_BOOT_COMPLETED, + OPSTR_NFC_CHANGE, + OPSTR_DATA_CONNECT_CHANGE, }; /** @@ -904,6 +937,10 @@ public class AppOpsManager { "MANAGE_IPSEC_TUNNELS", "START_FOREGROUND", "BLUETOOTH_SCAN", + "BLUETOOTH_CHANGE", + "BOOT_COMPLETED", + "NFC_CHANGE", + "DATA_CONNECT_CHANGE", }; /** @@ -921,7 +958,7 @@ public class AppOpsManager { android.Manifest.permission.WRITE_CALL_LOG, android.Manifest.permission.READ_CALENDAR, android.Manifest.permission.WRITE_CALENDAR, - android.Manifest.permission.ACCESS_WIFI_STATE, + null, // no permission for wifi scan available null, // no permission required for notifications null, // neighboring cells shares the coarse location perm android.Manifest.permission.CALL_PHONE, @@ -989,6 +1026,10 @@ public class AppOpsManager { null, // no permission for OP_MANAGE_IPSEC_TUNNELS Manifest.permission.FOREGROUND_SERVICE, null, // no permission for OP_BLUETOOTH_SCAN + null, + Manifest.permission.RECEIVE_BOOT_COMPLETED, + Manifest.permission.NFC, + null, }; /** @@ -1075,6 +1116,10 @@ public class AppOpsManager { null, // MANAGE_IPSEC_TUNNELS null, // START_FOREGROUND null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN + null, // BLUETOOTH_CHANGE + null, // BOOT_COMPLETED + null, // NFC_CHANGE + null, // DATA_CONNECT_CHANGE }; /** @@ -1160,6 +1205,10 @@ public class AppOpsManager { false, // MANAGE_IPSEC_HANDOVERS false, // START_FOREGROUND true, // BLUETOOTH_SCAN + true, // BLUETOOTH_CHANGE + true, // BOOT_COMPLETED + true, // NFC_CHANGE + true, // DATA_CONNECT_CHANGE }; /** @@ -1244,6 +1293,187 @@ public class AppOpsManager { AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS AppOpsManager.MODE_ALLOWED, // OP_START_FOREGROUND AppOpsManager.MODE_ALLOWED, // OP_BLUETOOTH_SCAN + AppOpsManager.MODE_ALLOWED, // OP_BLUETOOTH_CHANGE + AppOpsManager.MODE_ALLOWED, // OP_BOOT_COMPLETED + AppOpsManager.MODE_ALLOWED, // OP_NFC_CHANGE + AppOpsManager.MODE_ALLOWED, // OP_DATA_CONNECT_CHANGE + }; + + /** + * This specifies the default mode for each strict operation. + */ + + private static int[] sOpDefaultStrictMode = new int[] { + AppOpsManager.MODE_ASK, // OP_COARSE_LOCATION + AppOpsManager.MODE_ASK, // OP_FINE_LOCATION + AppOpsManager.MODE_ASK, // OP_GPS + AppOpsManager.MODE_ALLOWED, // OP_VIBRATE + AppOpsManager.MODE_ASK, // OP_READ_CONTACTS + AppOpsManager.MODE_ASK, // OP_WRITE_CONTACTS + AppOpsManager.MODE_ASK, // OP_READ_CALL_LOG + AppOpsManager.MODE_ASK, // OP_WRITE_CALL_LOG + AppOpsManager.MODE_ALLOWED, // OP_READ_CALENDAR + AppOpsManager.MODE_ALLOWED, // OP_WRITE_CALENDAR + AppOpsManager.MODE_ASK, // OP_WIFI_SCAN + AppOpsManager.MODE_ALLOWED, // OP_POST_NOTIFICATION + AppOpsManager.MODE_ALLOWED, // OP_NEIGHBORING_CELLS + AppOpsManager.MODE_ASK, // OP_CALL_PHONE + AppOpsManager.MODE_ASK, // OP_READ_SMS + AppOpsManager.MODE_ASK, // OP_WRITE_SMS + AppOpsManager.MODE_ASK, // OP_RECEIVE_SMS + AppOpsManager.MODE_ALLOWED, // OP_RECEIVE_EMERGECY_SMS + AppOpsManager.MODE_ASK, // OP_RECEIVE_MMS + AppOpsManager.MODE_ALLOWED, // OP_RECEIVE_WAP_PUSH + AppOpsManager.MODE_ASK, // OP_SEND_SMS + AppOpsManager.MODE_ALLOWED, // OP_READ_ICC_SMS + AppOpsManager.MODE_ALLOWED, // OP_WRITE_ICC_SMS + AppOpsManager.MODE_ALLOWED, // OP_WRITE_SETTINGS + AppOpsManager.MODE_ALLOWED, // OP_SYSTEM_ALERT_WINDOW + AppOpsManager.MODE_ALLOWED, // OP_ACCESS_NOTIFICATIONS + AppOpsManager.MODE_ASK, // OP_CAMERA + AppOpsManager.MODE_ASK, // OP_RECORD_AUDIO + AppOpsManager.MODE_ALLOWED, // OP_PLAY_AUDIO + AppOpsManager.MODE_ALLOWED, // OP_READ_CLIPBOARD + AppOpsManager.MODE_ALLOWED, // OP_WRITE_CLIPBOARD + AppOpsManager.MODE_ALLOWED, // OP_TAKE_MEDIA_BUTTONS + AppOpsManager.MODE_ALLOWED, // OP_TAKE_AUDIO_FOCUS + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_MASTER_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_VOICE_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_RING_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_MEDIA_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ALARM_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_NOTIFICATION_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_BLUETOOTH_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_WAKE_LOCK + AppOpsManager.MODE_ALLOWED, // OP_MONITOR_LOCATION + AppOpsManager.MODE_ASK, // OP_MONITOR_HIGH_POWER_LOCATION + AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS + AppOpsManager.MODE_ALLOWED, // OP_MUTE_MICROPHONE + AppOpsManager.MODE_ALLOWED, // OP_TOAST_WINDOW + AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA + AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN + AppOpsManager.MODE_ALLOWED, // OP WALLPAPER + AppOpsManager.MODE_ALLOWED, // OP_ASSIST_STRUCTURE + AppOpsManager.MODE_ALLOWED, // OP_ASSIST_SCREENSHOT + AppOpsManager.MODE_ALLOWED, // OP_READ_PHONE_STATE + AppOpsManager.MODE_ALLOWED, // OP_ADD_VOICEMAIL + AppOpsManager.MODE_ALLOWED, // OP_USE_SIP + AppOpsManager.MODE_ALLOWED, // OP_PROCESS_OUTGOING_CALLS + AppOpsManager.MODE_ALLOWED, // OP_USE_FINGERPRINT + AppOpsManager.MODE_ALLOWED, // OP_BODY_SENSORS + AppOpsManager.MODE_ALLOWED, // OP_READ_CELL_BROADCASTS + AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION + AppOpsManager.MODE_ALLOWED, // OP_READ_EXTERNAL_STORAGE + AppOpsManager.MODE_ALLOWED, // OP_WRITE_EXTERNAL_STORAGE + AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN + AppOpsManager.MODE_ALLOWED, // OP_GET_ACCOUNTS + AppOpsManager.MODE_ASK, // MODE_RUN_IN_BACKGROUND + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME + AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS + AppOpsManager.MODE_DEFAULT, // OP_REQUEST_INSTALL_PACKAGES + AppOpsManager.MODE_ALLOWED, // OP_PICTURE_IN_PICTURE + AppOpsManager.MODE_DEFAULT, // OP_INSTANT_APP_START_FOREGROUND + AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS + AppOpsManager.MODE_ASK, // OP_RUN_ANY_IN_BACKGROUND + AppOpsManager.MODE_ALLOWED, // OP_CHANGE_WIFI_STATE + AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES + AppOpsManager.MODE_ALLOWED, // OP_BIND_ACCESSIBILITY_SERVICE + AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER + AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS + AppOpsManager.MODE_ALLOWED, // OP_START_FOREGROUND + AppOpsManager.MODE_ALLOWED, // OP_BLUETOOTH_SCAN + AppOpsManager.MODE_ASK, // OP_BLUETOOTH_CHANGE + AppOpsManager.MODE_ASK, // OP_BOOT_COMPLETED + AppOpsManager.MODE_ASK, // OP_NFC_CHANGE + AppOpsManager.MODE_ASK, // OP_DATA_CONNECT_CHANGE + }; + + /** + * This specifies if operation is in strict mode. + */ + private final static boolean[] sOpStrictMode = new boolean[] { + true, // COARSE_LOCATION + true, // FINE_LOCATION + true, // GPS + false, // VIBRATE + true, // READ_CONTACTS + true, // WRITE_CONTACTS + true, // READ_CALL_LOG + true, // WRITE_CALL_LOG + false, // READ_CALENDAR + false, // WRITE_CALENDAR + true, // WIFI_SCAN + false, // POST_NOTIFICATION + false, // NEIGHBORING_CELLS + true, // CALL_PHONE + true, // READ_SMS + true, // WRITE_SMS + true, // RECEIVE_SMS + false, // RECEIVE_EMERGECY_SMS + true, // RECEIVE_MMS + false, // RECEIVE_WAP_PUSH + true, // SEND_SMS + true, // READ_ICC_SMS + true, // WRITE_ICC_SMS + true, // WRITE_SETTINGS + false, // SYSTEM_ALERT_WINDOW + false, // ACCESS_NOTIFICATIONS + true, // CAMERA + true, // RECORD_AUDIO + true, // PLAY_AUDIO + false, // READ_CLIPBOARD + false, // WRITE_CLIPBOARD + true, // TAKE_MEDIA_BUTTONS + true, // TAKE_AUDIO_FOCUS + false, // AUDIO_MASTER_VOLUME + false, // AUDIO_VOICE_VOLUME + false, // AUDIO_RING_VOLUME + false, // AUDIO_MEDIA_VOLUME + false, // AUDIO_ALARM_VOLUME + false, // AUDIO_NOTIFICATION_VOLUME + false, // AUDIO_BLUETOOTH_VOLUME + false, // WAKE_LOCK + true, // MONITOR_LOCATION + true, // MONITOR_HIGH_POWER_LOCATION + true, // GET_USAGE_STATS + false, // MUTE_MICROPHONE + false, // TOAST_WINDOW + true, // PROJECT_MEDIA + false, // ACTIVATE_VPN + false, // WALLPAPER + false, // ASSIST_STRUCTURE + false, // ASSIST_SCREENSHOT + true, // READ_PHONE_STATE + true, // ADD_VOICEMAIL + true, // USE_SIP + true, // PROCESS_OUTGOING_CALLS + true, // USE_FINGERPRINT + true, // BODY_SENSORS + false, // READ_CELL_BROADCASTS + true, // MOCK_LOCATION + true, // READ_EXTERNAL_STORAGE + true, // WRITE_EXTERNAL_STORAGE + false, // TURN_ON_SCREEN + false, // GET_ACCOUNTS + true, // RUN_IN_BACKGROUND + false, // AUDIO_ACCESSIBILITY_VOLUME + true, // READ_PHONE_NUMBERS + true, // REQUEST_INSTALL_PACKAGES + true, // ENTER_PICTURE_IN_PICTURE_ON_HIDE + true, // INSTANT_APP_START_FOREGROUND + false, // ANSWER_PHONE_CALLS + true, // OP_RUN_ANY_IN_BACKGROUND + false, // OP_CHANGE_WIFI_STATE + false, // OP_REQUEST_DELETE_PACKAGES + false, // OP_BIND_ACCESSIBILITY_SERVICE + false, // ACCEPT_HANDOVER + false, // MANAGE_IPSEC_HANDOVERS + false, // START_FOREGROUND + true, // BLUETOOTH_SCAN + true, // BLUETOOTH_CHANGE + true, // BOOT_COMPLETED + true, // NFC_CHANGE + true, // DATA_CONNECT_CHANGE }; /** @@ -1332,6 +1562,10 @@ public class AppOpsManager { false, // MANAGE_IPSEC_TUNNELS false, // START_FOREGROUND false, // BLUETOOTH_SCAN + false, // OP_BLUETOOTH_CHANGE + false, // OP_BOOT_COMPLETED + false, // OP_NFC_CHANGE + false, // OP_DATA_CONNECT_CHANGE }; /** @@ -1344,6 +1578,20 @@ public class AppOpsManager { */ private static HashMap sPermToOp = new HashMap<>(); + private static HashMap sNameToOp = new HashMap(); + + /** + * App op guard states. + * @hide + */ + public static final int[] PRIVACY_GUARD_OP_STATES = new int[] { + OP_COARSE_LOCATION, + OP_READ_CALL_LOG, + OP_READ_CONTACTS, + OP_READ_CALENDAR, + OP_READ_SMS, + }; + static { if (sOpToSwitch.length != _NUM_OP) { throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length @@ -1365,6 +1613,10 @@ public class AppOpsManager { throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length + " should be " + _NUM_OP); } + if (sOpDefaultStrictMode.length != _NUM_OP) { + throw new IllegalStateException("sOpDefaultStrictMode length " + + sOpDefaultStrictMode.length + " should be " + _NUM_OP); + } if (sOpDisableReset.length != _NUM_OP) { throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length + " should be " + _NUM_OP); @@ -1377,6 +1629,10 @@ public class AppOpsManager { throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length " + sOpRestrictions.length + " should be " + _NUM_OP); } + if (sOpStrictMode.length != _NUM_OP) { + throw new IllegalStateException("sOpStrictMode length " + sOpStrictMode.length + + " should be " + _NUM_OP); + } for (int i=0; i<_NUM_OP; i++) { if (sOpToString[i] != null) { sOpStrToOp.put(sOpToString[i], i); @@ -1387,6 +1643,9 @@ public class AppOpsManager { sPermToOp.put(sOpPerms[op], op); } } + for (int i=0; i<_NUM_OP; i++) { + sNameToOp.put(sOpNames[i], i); + } } /** @@ -1418,6 +1677,15 @@ public static int strDebugOpToOp(String op) { throw new IllegalArgumentException("Unknown operation string: " + op); } + /** + * Map a non-localized name for the operation back to the Op number + * @hide + */ + public static int nameToOp(String name) { + Integer val = sNameToOp.get(name); + return val != null ? val : OP_NONE; + } + /** * Retrieve the permission associated with an operation, or null if there is not one. * @hide @@ -1458,10 +1726,17 @@ public static boolean opAllowSystemBypassRestriction(int op) { * Retrieve the default mode for the operation. * @hide */ - public static int opToDefaultMode(int op) { + public static int opToDefaultMode(int op, boolean isStrict) { + if (isStrict) { + return sOpDefaultStrictMode[op]; + } return sOpDefaultMode[op]; } + public static int opToDefaultMode(int op) { + return opToDefaultMode(op, false); + } + /** * Retrieve the human readable mode. * @hide @@ -1557,9 +1832,11 @@ public static class OpEntry implements Parcelable { private final int mProxyUid; private final boolean mRunning; private final String mProxyPackageName; + private final int mAllowedCount; + private final int mIgnoredCount; public OpEntry(int op, int mode, long time, long rejectTime, int duration, - int proxyUid, String proxyPackage) { + int proxyUid, String proxyPackage, int allowedCount, int ignoredCount) { mOp = op; mMode = mode; mTimes = new long[_NUM_UID_STATE]; @@ -1570,10 +1847,13 @@ public OpEntry(int op, int mode, long time, long rejectTime, int duration, mRunning = duration == -1; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; + mAllowedCount = allowedCount; + mIgnoredCount = ignoredCount; } public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, - boolean running, int proxyUid, String proxyPackage) { + boolean running, int proxyUid, String proxyPackage, + int allowedCount, int ignoredCount) { mOp = op; mMode = mode; mTimes = new long[_NUM_UID_STATE]; @@ -1584,11 +1864,14 @@ public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, mRunning = running; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; + mAllowedCount = allowedCount; + mIgnoredCount = ignoredCount; } public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, - int proxyUid, String proxyPackage) { - this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage); + int proxyUid, String proxyPackage, int allowedCount, int ignoredCount) { + this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage, + allowedCount, ignoredCount); } public int getOp() { @@ -1655,6 +1938,14 @@ public String getProxyPackageName() { return mProxyPackageName; } + public int getAllowedCount() { + return mAllowedCount; + } + + public int getIgnoredCount() { + return mIgnoredCount; + } + @Override public int describeContents() { return 0; @@ -1670,6 +1961,8 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeBoolean(mRunning); dest.writeInt(mProxyUid); dest.writeString(mProxyPackageName); + dest.writeInt(mAllowedCount); + dest.writeInt(mIgnoredCount); } OpEntry(Parcel source) { @@ -1681,6 +1974,8 @@ public void writeToParcel(Parcel dest, int flags) { mRunning = source.readBoolean(); mProxyUid = source.readInt(); mProxyPackageName = source.readString(); + mAllowedCount = source.readInt(); + mIgnoredCount = source.readInt(); } public static final Creator CREATOR = new Creator() { @@ -2589,4 +2884,37 @@ public static long maxTime(long[] times, int start, int end) { } return time; } + + /** + * Check if op in strict mode + * @hide + */ + public static boolean isStrictOp(int code) { + return sOpStrictMode[code]; + } + + /** @hide */ + public boolean getPrivacyGuardSettingForPackage(int uid, String packageName) { + try { + return mService.getPrivacyGuardSettingForPackage(uid, packageName); + } catch (RemoteException e) { + } + return false; + } + + /** @hide */ + public void setPrivacyGuardSettingForPackage(int uid, String packageName, boolean state) { + try { + mService.setPrivacyGuardSettingForPackage(uid, packageName, state); + } catch (RemoteException e) { + } + } + + /** @hide */ + public void resetCounters() { + try { + mService.resetCounters(); + } catch (RemoteException e) { + } + } } diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index b444f17c0b69..8ffe16f39e64 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -127,6 +127,9 @@ public class DownloadManager { */ public final static String COLUMN_STATUS = Downloads.Impl.COLUMN_STATUS; + /** {@hide} */ + public static final String COLUMN_FILE_NAME_HINT = Downloads.Impl.COLUMN_FILE_NAME_HINT; + /** * Provides more detail on the status of the download. Its meaning depends on the value of * {@link #COLUMN_STATUS}. @@ -164,6 +167,9 @@ public class DownloadManager { */ public static final String COLUMN_MEDIAPROVIDER_URI = Downloads.Impl.COLUMN_MEDIAPROVIDER_URI; + /** {@hide} */ + public static final String COLUMN_DESTINATION = Downloads.Impl.COLUMN_DESTINATION; + /** * @hide */ @@ -279,6 +285,13 @@ public class DownloadManager { */ public final static int PAUSED_UNKNOWN = 4; + /** + * Value of {@link #COLUMN_REASON} when the download is paused manually. + * + * @hide + */ + public final static int PAUSED_MANUAL = 5; + /** * Broadcast intent action sent by the download manager when a download completes. */ @@ -330,26 +343,22 @@ public class DownloadManager { * @hide */ public static final String[] UNDERLYING_COLUMNS = new String[] { - Downloads.Impl._ID, - Downloads.Impl._DATA + " AS " + COLUMN_LOCAL_FILENAME, - Downloads.Impl.COLUMN_MEDIAPROVIDER_URI, - Downloads.Impl.COLUMN_DESTINATION, - Downloads.Impl.COLUMN_TITLE, - Downloads.Impl.COLUMN_DESCRIPTION, - Downloads.Impl.COLUMN_URI, - Downloads.Impl.COLUMN_STATUS, - Downloads.Impl.COLUMN_FILE_NAME_HINT, - Downloads.Impl.COLUMN_MIME_TYPE + " AS " + COLUMN_MEDIA_TYPE, - Downloads.Impl.COLUMN_TOTAL_BYTES + " AS " + COLUMN_TOTAL_SIZE_BYTES, - Downloads.Impl.COLUMN_LAST_MODIFICATION + " AS " + COLUMN_LAST_MODIFIED_TIMESTAMP, - Downloads.Impl.COLUMN_CURRENT_BYTES + " AS " + COLUMN_BYTES_DOWNLOADED_SO_FAR, - Downloads.Impl.COLUMN_ALLOW_WRITE, - /* add the following 'computed' columns to the cursor. - * they are not 'returned' by the database, but their inclusion - * eliminates need to have lot of methods in CursorTranslator - */ - "'placeholder' AS " + COLUMN_LOCAL_URI, - "'placeholder' AS " + COLUMN_REASON + DownloadManager.COLUMN_ID, + DownloadManager.COLUMN_LOCAL_FILENAME, + DownloadManager.COLUMN_MEDIAPROVIDER_URI, + DownloadManager.COLUMN_DESTINATION, + DownloadManager.COLUMN_TITLE, + DownloadManager.COLUMN_DESCRIPTION, + DownloadManager.COLUMN_URI, + DownloadManager.COLUMN_STATUS, + DownloadManager.COLUMN_FILE_NAME_HINT, + DownloadManager.COLUMN_MEDIA_TYPE, + DownloadManager.COLUMN_TOTAL_SIZE_BYTES, + DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP, + DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR, + DownloadManager.COLUMN_ALLOW_WRITE, + DownloadManager.COLUMN_LOCAL_URI, + DownloadManager.COLUMN_REASON }; /** @@ -930,6 +939,7 @@ Cursor runQuery(ContentResolver resolver, String[] projection, Uri baseUri) { parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY)); parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK)); parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI)); + parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_MANUAL)); } if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) { parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS)); @@ -1180,6 +1190,34 @@ public void forceDownload(long... ids) { mResolver.update(mBaseUri, values, getWhereClauseForIds(ids), getWhereArgsForIds(ids)); } + /** + * Pause the given running download manually. + * + * @param id the ID of the download to be paused + * @return the number of downloads actually updated + * @hide + */ + public int pauseDownload(long id) { + ContentValues values = new ContentValues(); + values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PAUSED_MANUAL); + + return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values, null, null); + } + + /** + * Resume the given paused download manually. + * + * @param id the ID of the download to be resumed + * @return the number of downloads actually updated + * @hide + */ + public int resumeDownload(long id) { + ContentValues values = new ContentValues(); + values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_RUNNING); + + return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values, null, null); + } + /** * Returns maximum size, in bytes, of downloads that may go over a mobile connection; or null if * there's no limit @@ -1564,6 +1602,9 @@ private long getPausedReason(int status) { case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: return PAUSED_QUEUED_FOR_WIFI; + case Downloads.Impl.STATUS_PAUSED_MANUAL: + return PAUSED_MANUAL; + default: return PAUSED_UNKNOWN; } @@ -1619,6 +1660,7 @@ private int translateStatus(int status) { case Downloads.Impl.STATUS_WAITING_TO_RETRY: case Downloads.Impl.STATUS_WAITING_FOR_NETWORK: case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: + case Downloads.Impl.STATUS_PAUSED_MANUAL: return STATUS_PAUSED; case Downloads.Impl.STATUS_SUCCESS: diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index b192021f821b..e234a23bdf8d 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -278,7 +278,8 @@ interface IActivityManager { boolean isImmersive(in IBinder token); void setImmersive(in IBinder token, boolean immersive); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message); + void crashApplication(int uid, int initialPid, in String packageName, int userId, + in String message, boolean force); String getProviderMimeType(in Uri uri, int userId); IBinder newUriPermissionOwner(in String name); void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg, @@ -714,4 +715,9 @@ interface IActivityManager { /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ void alwaysShowUnsupportedCompileSdkWarning(in ComponentName activity); + + /** + * Should disable touch if three fingers to screen shot is active? + */ + boolean isSwipeToScreenshotGestureActive(); } diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl index ded4c4954956..614de779c767 100644 --- a/core/java/android/app/IAlarmManager.aidl +++ b/core/java/android/app/IAlarmManager.aidl @@ -38,4 +38,6 @@ interface IAlarmManager { long getNextWakeFromIdleTime(); AlarmManager.AlarmClockInfo getNextAlarmClock(int userId); long currentNetworkTimeMillis(); + // update the uids being synchronized by network socket request manager + void updateBlockedUids(int uid, boolean isBlocked); } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index cd127102f83b..f2d158030db8 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -165,4 +165,7 @@ interface INotificationManager void applyRestore(in byte[] payload, int user); ParceledListSlice getAppActiveNotifications(String callingPkg, int userId); + + void forceShowLedLight(int color); + void forcePulseLedLight(int color, int onTime, int offTime); } diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index d4385549da02..24177507e459 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -461,6 +461,7 @@ public Activity startActivitySync(Intent intent) { */ @NonNull public Activity startActivitySync(@NonNull Intent intent, @Nullable Bundle options) { + android.util.SeempLog.record_str(376, intent.toString()); validateNotAppThread(); synchronized (mSync) { @@ -1635,6 +1636,7 @@ public Intent getResultData() { public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { + android.util.SeempLog.record_str(377, intent.toString()); IApplicationThread whoThread = (IApplicationThread) contextThread; Uri referrer = target != null ? target.onProvideReferrer() : null; if (referrer != null) { @@ -1706,6 +1708,7 @@ public void execStartActivities(Context who, IBinder contextThread, public int execStartActivitiesAsUser(Context who, IBinder contextThread, IBinder token, Activity target, Intent[] intents, Bundle options, int userId) { + android.util.SeempLog.record_str(378, intents.toString()); IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { @@ -1777,6 +1780,7 @@ public int execStartActivitiesAsUser(Context who, IBinder contextThread, public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { + android.util.SeempLog.record_str(377, intent.toString()); IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { @@ -1844,6 +1848,7 @@ public ActivityResult execStartActivity( public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String resultWho, Intent intent, int requestCode, Bundle options, UserHandle user) { + android.util.SeempLog.record_str(377, intent.toString()); IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { @@ -1890,6 +1895,7 @@ public ActivityResult execStartActivityAsCaller( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity, int userId) { + android.util.SeempLog.record_str(379, intent.toString()); IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { @@ -1935,6 +1941,7 @@ public ActivityResult execStartActivityAsCaller( public void execStartActivityFromAppTask( Context who, IBinder contextThread, IAppTask appTask, Intent intent, Bundle options) { + android.util.SeempLog.record_str(380, intent.toString()); IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 494b5474ad00..b373e3fbb847 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -1051,7 +1051,7 @@ public Application makeApplication(boolean forceDefaultAppClass, try { java.lang.ClassLoader cl = getClassLoader(); - if (!mPackageName.equals("android")) { + if (!ActivityThread.isSystem()) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader"); initializeJavaContextClassLoader(); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c179e3ca48af..2c51fc901514 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -195,7 +195,7 @@ public class Notification implements Parcelable *

* Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -500,6 +500,23 @@ public class Notification implements Parcelable @Deprecated public int defaults; + /** + * @hide + */ + public int backgroundColor; + /** + * @hide + */ + public int foregroundColor; + /** + * @hide + */ + public int primaryTextColor; + /** + * @hide + */ + public int secondaryTextColor; + /** * Bit to be bitwise-ored into the {@link #flags} field that should be * set if you want the LED on for this notification. @@ -2209,6 +2226,11 @@ private void readFromParcelImpl(Parcel parcel) } mGroupAlertBehavior = parcel.readInt(); + + backgroundColor = parcel.readInt(); + foregroundColor = parcel.readInt(); + primaryTextColor = parcel.readInt(); + secondaryTextColor = parcel.readInt(); } @Override @@ -2327,6 +2349,11 @@ public void cloneInto(Notification that, boolean heavy) { if (!heavy) { that.lightenPayload(); // will clean out extras } + + that.backgroundColor = this.backgroundColor; + that.foregroundColor = this.foregroundColor; + that.primaryTextColor = this.primaryTextColor; + that.secondaryTextColor = this.secondaryTextColor; } /** @@ -2642,6 +2669,11 @@ private void writeToParcelImpl(Parcel parcel, int flags) { parcel.writeInt(mGroupAlertBehavior); + parcel.writeInt(backgroundColor); + parcel.writeInt(foregroundColor); + parcel.writeInt(primaryTextColor); + parcel.writeInt(secondaryTextColor); + // mUsesStandardHeader is not written because it should be recomputed in listeners } @@ -3167,7 +3199,11 @@ public static class Builder { */ private static final int LIGHTNESS_TEXT_DIFFERENCE_DARK = -10; + private static final String MEDIA_ARTWORK_COLORIZED_EXTRAS = + "notification.mediaArtworkColorized"; + private Context mContext; + private Context mThemeContext; private Notification mN; private Bundle mUserExtras = new Bundle(); private Style mStyle; @@ -3211,6 +3247,7 @@ public static class Builder { private boolean mTintActionButtons; private boolean mInNightMode; + private boolean mAllowIconTextTint; /** * Constructs a new Builder with the defaults: @@ -3242,15 +3279,26 @@ public Builder(Context context) { * @hide */ public Builder(Context context, Notification toAdopt) { + this(context, toAdopt, context); + } + + /** + * @hide + */ + public Builder(Context context, Notification toAdopt, Context themeContext) { mContext = context; - Resources res = mContext.getResources(); + mThemeContext = themeContext; + Resources res = mThemeContext.getResources(); mTintActionButtons = res.getBoolean(R.bool.config_tintNotificationActionButtons); + mAllowIconTextTint = res.getBoolean(R.bool.config_allowNotificationIconTextTinting); if (res.getBoolean(R.bool.config_enableNightMode)) { Configuration currentConfig = res.getConfiguration(); mInNightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } + // UI_MODE_NIGHT doesnt seem to be ready, so just listen to config + mInNightMode = getColorUtil().getNightModeNotification(mContext); if (toAdopt == null) { mN = new Notification(); @@ -3306,11 +3354,25 @@ public Builder(Context context, Notification toAdopt) { private NotificationColorUtil getColorUtil() { if (mColorUtil == null) { - mColorUtil = NotificationColorUtil.getInstance(mContext); + mColorUtil = NotificationColorUtil.getInstance(mThemeContext); } return mColorUtil; } + /** + * @hide + */ + public void setArtworkColorizedExtras(boolean value) { + mN.extras.putBoolean(MEDIA_ARTWORK_COLORIZED_EXTRAS, true); + } + + /** + * @hide + */ + public boolean getArtworkColorizedExtras() { + return mN.extras.getBoolean(MEDIA_ARTWORK_COLORIZED_EXTRAS, false); + } + /** * If this notification is duplicative of a Launcher shortcut, sets the * {@link ShortcutInfo#getId() id} of the shortcut, in case the Launcher wants to hide @@ -4298,7 +4360,7 @@ private Bitmap getProfileBadge() { if (badge == null) { return null; } - final int size = mContext.getResources().getDimensionPixelSize( + final int size = mThemeContext.getResources().getDimensionPixelSize( R.dimen.notification_badge_size); Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); @@ -4389,7 +4451,7 @@ private RemoteViews applyStandardTemplate(int resId, boolean hasProgress, private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p, TemplateBindResult result) { - RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId); + RemoteViews contentView = new BuilderRemoteViews(mThemeContext.getApplicationInfo(), resId); resetStandardTemplate(contentView); @@ -4426,6 +4488,11 @@ private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p, private CharSequence processTextSpans(CharSequence text) { if (hasForegroundColor()) { return NotificationColorUtil.clearColorSpans(text); + } else if (mContext.getResources() + .getBoolean(R.bool.config_useDarkBgNotificationIconTextTinting)) { + // Some notifications have color spans, assuming a dark background, + // so let's remove them + return NotificationColorUtil.clearColorSpans(text); } return text; } @@ -4471,9 +4538,9 @@ private void ensureColors() { || mTextColorsAreForBackground != backgroundColor) { mTextColorsAreForBackground = backgroundColor; if (!hasForegroundColor() || !isColorized()) { - mPrimaryTextColor = NotificationColorUtil.resolvePrimaryColor(mContext, + mPrimaryTextColor = NotificationColorUtil.resolvePrimaryColor(mThemeContext, backgroundColor); - mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor(mContext, + mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor(mThemeContext, backgroundColor); if (backgroundColor != COLOR_DEFAULT && isColorized()) { mPrimaryTextColor = NotificationColorUtil.findAlphaToMeetContrast( @@ -4541,6 +4608,11 @@ && satisfiesTextContrast(backgroundColor, Color.BLACK) } } } + + mN.backgroundColor = backgroundColor; + mN.foregroundColor = mForegroundColor; + mN.primaryTextColor = mPrimaryTextColor; + mN.secondaryTextColor = mSecondaryTextColor; } private void updateBackgroundColor(RemoteViews contentView) { @@ -4563,7 +4635,7 @@ void setContentMinHeight(RemoteViews remoteView, boolean hasMinHeight) { int minHeight = 0; if (hasMinHeight) { // we need to set the minHeight of the notification - minHeight = mContext.getResources().getDimensionPixelSize( + minHeight = mThemeContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.notification_min_content_height); } remoteView.setInt(R.id.notification_main_column, "setMinimumHeight", minHeight); @@ -4578,7 +4650,7 @@ private boolean handleProgressBar(boolean hasProgress, RemoteViews contentView, contentView.setProgressBar( R.id.progress, max, progress, ind); contentView.setProgressBackgroundTintList( - R.id.progress, ColorStateList.valueOf(mContext.getColor( + R.id.progress, ColorStateList.valueOf(mThemeContext.getColor( R.color.notification_progress_background_color))); if (mN.color != COLOR_DEFAULT) { ColorStateList colorStateList = ColorStateList.valueOf(resolveContrastColor()); @@ -4825,7 +4897,7 @@ private void bindHeaderAppName(RemoteViews contentView, boolean ambient) { setTextViewColorPrimary(contentView, R.id.app_name_text); } else { contentView.setTextColor(R.id.app_name_text, - ambient ? resolveAmbientColor() : getSecondaryTextColor()); + ambient ? resolveAmbientColor() : resolveAppNameTinting()); } } @@ -5029,7 +5101,7 @@ public RemoteViews createBigContentView() { public RemoteViews makeNotificationHeader(boolean ambient) { Boolean colorized = (Boolean) mN.extras.get(EXTRA_COLORIZED); mN.extras.putBoolean(EXTRA_COLORIZED, false); - RemoteViews header = new BuilderRemoteViews(mContext.getApplicationInfo(), + RemoteViews header = new BuilderRemoteViews(mThemeContext.getApplicationInfo(), ambient ? R.layout.notification_template_ambient_header : R.layout.notification_template_header); resetNotificationHeader(header); @@ -5157,7 +5229,7 @@ private RemoteViews makePublicView(boolean ambient) { RemoteViews view; if (ambient) { publicExtras.putCharSequence(EXTRA_TITLE, - mContext.getString(com.android.internal.R.string.notification_hidden_text)); + mThemeContext.getString(com.android.internal.R.string.notification_hidden_text)); view = makeAmbientNotification(); } else{ view = makeNotificationHeader(false /* ambient */); @@ -5216,7 +5288,7 @@ private CharSequence createSummaryText() { } CharSequence contentText = mN.extras.getCharSequence(Notification.EXTRA_TEXT); if (titleText != null && contentText != null) { - summary.append(bidi.unicodeWrap(mContext.getText( + summary.append(bidi.unicodeWrap(mThemeContext.getText( R.string.notification_header_divider_symbol_with_spaces))); } if (contentText != null) { @@ -5228,7 +5300,7 @@ private CharSequence createSummaryText() { private RemoteViews generateActionButton(Action action, boolean emphazisedMode, boolean ambient) { final boolean tombstone = (action.actionIntent == null); - RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(), + RemoteViews button = new BuilderRemoteViews(mThemeContext.getApplicationInfo(), emphazisedMode ? getEmphasizedActionLayoutResource() : tombstone ? getActionTombstoneLayoutResource() : getActionLayoutResource()); @@ -5258,7 +5330,7 @@ private RemoteViews generateActionButton(Action action, boolean emphazisedMode, // There's a span spanning the full text, let's take it and use it as the // background color background = outResultColor[0].getDefaultColor(); - int textColor = NotificationColorUtil.resolvePrimaryColor(mContext, + int textColor = NotificationColorUtil.resolvePrimaryColor(mThemeContext, background); button.setTextColor(R.id.action0, textColor); rippleColor = textColor; @@ -5378,7 +5450,7 @@ private CharSequence processLegacyText(CharSequence charSequence) { private CharSequence processLegacyText(CharSequence charSequence, boolean ambient) { boolean isAlreadyLightText = isLegacy() || textColorsNeedInversion(); - boolean wantLightText = ambient; + boolean wantLightText = ambient || getColorUtil().getDarkNotificationTinting(mContext); if (isAlreadyLightText != wantLightText) { return getColorUtil().invertCharSequenceColors(charSequence); } else { @@ -5398,7 +5470,7 @@ private void processSmallIconColor(Icon smallIcon, RemoteViews contentView, } else if (isColorized()) { color = getPrimaryTextColor(); } else { - color = resolveContrastColor(); + color = resolveIconContrastColor(); } if (colorable) { contentView.setDrawableTint(R.id.icon, false, color, @@ -5418,7 +5490,7 @@ private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) { if (largeIcon != null && isLegacy() && getColorUtil().isGrayscaleIcon(mContext, largeIcon)) { // resolve color will fall back to the default when legacy - contentView.setDrawableTint(R.id.icon, false, resolveContrastColor(), + contentView.setDrawableTint(R.id.icon, false, resolveIconContrastColor(), PorterDuff.Mode.SRC_ATOP); } } @@ -5429,20 +5501,42 @@ private void sanitizeColor() { } } + int resolveIconContrastColor() { + if (!mAllowIconTextTint) { + return mThemeContext.getColor(R.color.notification_icon_default_color); + } else { + return resolveContrastColor(); + } + } + + int resolveAppNameTinting() { + if (!mContext.getResources().getBoolean(R.bool.config_allowNotificationAppNameTextTinting)) { + return getSecondaryTextColor(); + } else { + return resolveContrastColor(); + } + } + int resolveContrastColor() { + if (!mAllowIconTextTint) { + return mThemeContext.getColor(R.color.notification_text_default_color); + } + if (mCachedContrastColorIsFor == mN.color && mCachedContrastColor != COLOR_INVALID) { return mCachedContrastColor; } int color; - int background = mContext.getColor( + int background = mThemeContext.getColor( com.android.internal.R.color.notification_material_background_color); if (mN.color == COLOR_DEFAULT) { ensureColors(); - color = NotificationColorUtil.resolveDefaultColor(mContext, background); + color = NotificationColorUtil.resolveDefaultColor(mThemeContext, background); } else { - color = NotificationColorUtil.resolveContrastColor(mContext, mN.color, - background, mInNightMode); + boolean isDark = mInNightMode || mContext.getResources() + .getBoolean(R.bool.config_useDarkBgNotificationIconTextTinting); + color = NotificationColorUtil.resolveContrastColor(mThemeContext, mN.color, + background, isDark); } if (Color.alpha(color) < 255) { // alpha doesn't go well for color filters, so let's blend it manually @@ -5467,10 +5561,13 @@ int resolveNeutralColor() { } int resolveAmbientColor() { + if (!mContext.getResources().getBoolean(R.bool.config_allowNotificationIconTextTinting)) { + return mContext.getColor(R.color.notification_ambient_icon_default_color); + } if (mCachedAmbientColorIsFor == mN.color && mCachedAmbientColorIsFor != COLOR_INVALID) { return mCachedAmbientColor; } - final int contrasted = NotificationColorUtil.resolveAmbientColor(mContext, mN.color); + final int contrasted = NotificationColorUtil.resolveAmbientColor(mThemeContext, mN.color); mCachedAmbientColorIsFor = mN.color; return mCachedAmbientColor = contrasted; @@ -5517,7 +5614,7 @@ public static Notification.Builder recoverBuilder(Context context, Notification builderContext = context; // try with given context } - return new Builder(builderContext, n); + return new Builder(builderContext, n, context); } /** @@ -6895,7 +6992,7 @@ private void fixTitleAndTextExtras(Bundle extras) { if (!TextUtils.isEmpty(mConversationTitle)) { if (!TextUtils.isEmpty(sender)) { BidiFormatter bidi = BidiFormatter.getInstance(); - title = mBuilder.mContext.getString( + title = mBuilder.mThemeContext.getString( com.android.internal.R.string.notification_messaging_title_template, bidi.unicodeWrap(mConversationTitle), bidi.unicodeWrap(sender)); } else { @@ -7240,7 +7337,7 @@ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person send */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender, boolean remoteInputHistory) { - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; mRemoteInputHistory = remoteInputHistory; @@ -7350,7 +7447,7 @@ private Bundle toBundle() { bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { // Legacy listeners need this - bundle.putCharSequence(KEY_SENDER, mSender.getName()); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName())); bundle.putParcelable(KEY_SENDER_PERSON, mSender); } if (mDataMimeType != null) { @@ -7559,7 +7656,7 @@ public RemoteViews makeBigContentView() { } int i=0; - int topPadding = mBuilder.mContext.getResources().getDimensionPixelSize( + int topPadding = mBuilder.mThemeContext.getResources().getDimensionPixelSize( R.dimen.notification_inbox_item_top_padding); boolean first = true; int onlyViewId = 0; @@ -7610,7 +7707,7 @@ public RemoteViews makeBigContentView() { } if (onlyViewId != 0) { // We only have 1 entry, lets make it look like the normal Text of a Bigtext - topPadding = mBuilder.mContext.getResources().getDimensionPixelSize( + topPadding = mBuilder.mThemeContext.getResources().getDimensionPixelSize( R.dimen.notification_text_margin_top); contentView.setViewPadding(onlyViewId, 0, topPadding, 0, 0); } @@ -7831,7 +7928,7 @@ private RemoteViews generateMediaActionButton(Action action, int color) { // notification color. Otherwise, just use the passed-in color. int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized() ? color - : NotificationColorUtil.resolveColor(mBuilder.mContext, + : NotificationColorUtil.resolveColor(mBuilder.mThemeContext, Notification.COLOR_DEFAULT); button.setDrawableTint(R.id.action0, false, tintColor, diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index ba355f9f9c1d..1296311da796 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -68,6 +68,8 @@ public final class NotificationChannel implements Parcelable { private static final String ATT_IMPORTANCE = "importance"; private static final String ATT_LIGHTS = "lights"; private static final String ATT_LIGHT_COLOR = "light_color"; + private static final String ATT_ON_TIME = "light_on_time"; + private static final String ATT_OFF_TIME = "light_off_time"; private static final String ATT_VIBRATION = "vibration"; private static final String ATT_VIBRATION_ENABLED = "vibration_enabled"; private static final String ATT_SOUND = "sound"; @@ -125,6 +127,8 @@ public final class NotificationChannel implements Parcelable { }; private static final int DEFAULT_LIGHT_COLOR = 0; + private static final int DEFAULT_ON_TIME = 0; + private static final int DEFAULT_OFF_TIME = 0; private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE; private static final int DEFAULT_IMPORTANCE = @@ -141,6 +145,8 @@ public final class NotificationChannel implements Parcelable { private Uri mSound = Settings.System.DEFAULT_NOTIFICATION_URI; private boolean mLights; private int mLightColor = DEFAULT_LIGHT_COLOR; + private int mLightOnTime = DEFAULT_ON_TIME; + private int mLightOffTime = DEFAULT_OFF_TIME; private long[] mVibration; // Bitwise representation of fields that have been changed by the user, preventing the app from // making changes to these fields. @@ -213,6 +219,8 @@ protected NotificationChannel(Parcel in) { } mAudioAttributes = in.readInt() > 0 ? AudioAttributes.CREATOR.createFromParcel(in) : null; mLightColor = in.readInt(); + mLightOnTime = in.readInt(); + mLightOffTime = in.readInt(); mBlockableSystem = in.readBoolean(); } @@ -265,6 +273,8 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(0); } dest.writeInt(mLightColor); + dest.writeInt(mLightOnTime); + dest.writeInt(mLightOffTime); dest.writeBoolean(mBlockableSystem); } @@ -397,6 +407,30 @@ public void setLightColor(int argb) { this.mLightColor = argb; } + /** + * Sets the notification light ON time for notifications posted to this channel, if lights are + * {@link #enableLights(boolean) enabled} on this channel and the device supports that feature. + * + * Only modifiable before the channel is submitted to + * {@link NotificationManager#notify(String, int, Notification)}. + * @hide + */ + public void setLightOnTime(int time) { + this.mLightOnTime = time; + } + + /** + * Sets the notification light OFF time for notifications posted to this channel, if lights are + * {@link #enableLights(boolean) enabled} on this channel and the device supports that feature. + * + * Only modifiable before the channel is submitted to + * {@link NotificationManager#notify(String, int, Notification)}. + * @hide + */ + public void setLightOffTime(int time) { + this.mLightOffTime = time; + } + /** * Sets whether notification posted to this channel should vibrate. The vibration pattern can * be set with {@link #setVibrationPattern(long[])}. @@ -526,6 +560,24 @@ public int getLightColor() { return mLightColor; } + /** + * Returns the notification light ON time for notifications posted to this channel. Irrelevant + * unless {@link #shouldShowLights()}. + * @hide + */ + public int getLightOnTime() { + return mLightOnTime; + } + + /** + * Returns the notification light OFF time for notifications posted to this channel. Irrelevant + * unless {@link #shouldShowLights()}. + * @hide + */ + public int getLightOffTime() { + return mLightOffTime; + } + /** * Returns whether notifications posted to this channel always vibrate. */ @@ -632,6 +684,8 @@ private void populateFromXml(XmlPullParser parser, boolean forRestore, enableLights(safeBool(parser, ATT_LIGHTS, false)); setLightColor(safeInt(parser, ATT_LIGHT_COLOR, DEFAULT_LIGHT_COLOR)); + setLightOnTime(safeInt(parser, ATT_ON_TIME, DEFAULT_ON_TIME)); + setLightOffTime(safeInt(parser, ATT_OFF_TIME, DEFAULT_OFF_TIME)); setVibrationPattern(safeLongArray(parser, ATT_VIBRATION, null)); enableVibration(safeBool(parser, ATT_VIBRATION_ENABLED, false)); setShowBadge(safeBool(parser, ATT_SHOW_BADGE, false)); @@ -734,6 +788,12 @@ private void writeXml(XmlSerializer out, boolean forBackup, @Nullable Context co if (getLightColor() != DEFAULT_LIGHT_COLOR) { out.attribute(null, ATT_LIGHT_COLOR, Integer.toString(getLightColor())); } + if (getLightOnTime() != DEFAULT_ON_TIME) { + out.attribute(null, ATT_ON_TIME, Integer.toString(getLightOnTime())); + } + if (getLightOffTime() != DEFAULT_OFF_TIME) { + out.attribute(null, ATT_OFF_TIME, Integer.toString(getLightOffTime())); + } if (shouldVibrate()) { out.attribute(null, ATT_VIBRATION_ENABLED, Boolean.toString(shouldVibrate())); } @@ -792,6 +852,8 @@ public JSONObject toJson() throws JSONException { } record.put(ATT_LIGHTS, Boolean.toString(shouldShowLights())); record.put(ATT_LIGHT_COLOR, Integer.toString(getLightColor())); + record.put(ATT_ON_TIME, Integer.toString(getLightOnTime())); + record.put(ATT_OFF_TIME, Integer.toString(getLightOffTime())); record.put(ATT_VIBRATION_ENABLED, Boolean.toString(shouldVibrate())); record.put(ATT_USER_LOCKED, Integer.toString(getUserLockedFields())); record.put(ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown())); @@ -895,6 +957,8 @@ public boolean equals(Object o) { if (getLockscreenVisibility() != that.getLockscreenVisibility()) return false; if (mLights != that.mLights) return false; if (getLightColor() != that.getLightColor()) return false; + if (getLightOnTime() != that.getLightOnTime()) return false; + if (getLightOffTime() != that.getLightOffTime()) return false; if (getUserLockedFields() != that.getUserLockedFields()) return false; if (mVibrationEnabled != that.mVibrationEnabled) return false; if (mShowBadge != that.mShowBadge) return false; @@ -931,6 +995,8 @@ public int hashCode() { result = 31 * result + (getSound() != null ? getSound().hashCode() : 0); result = 31 * result + (mLights ? 1 : 0); result = 31 * result + getLightColor(); + result = 31 * result + getLightOnTime(); + result = 31 * result + getLightOffTime(); result = 31 * result + Arrays.hashCode(mVibration); result = 31 * result + getUserLockedFields(); result = 31 * result + (mVibrationEnabled ? 1 : 0); @@ -954,6 +1020,8 @@ public String toString() { + ", mSound=" + mSound + ", mLights=" + mLights + ", mLightColor=" + mLightColor + + ", mLightOnTime=" + mLightOnTime + + ", mLightOffTime=" + mLightOffTime + ", mVibration=" + Arrays.toString(mVibration) + ", mUserLockedFields=" + Integer.toHexString(mUserLockedFields) + ", mFgServiceShown=" + mFgServiceShown diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index f6dc5d15f385..36ae818d2301 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1578,4 +1578,23 @@ public static int zenModeFromInterruptionFilter(int interruptionFilter, int defV } } + /** @hide */ + public void forceShowLedLight(int color) { + final INotificationManager service = getService(); + try { + service.forceShowLedLight(color); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** @hide */ + public void forcePulseLedLight(int color, int onTime, int offTime) { + final INotificationManager service = getService(); + try { + service.forcePulseLedLight(color, onTime, offTime); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index af55788e617f..6b30ec4d536f 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -19,24 +19,25 @@ import static android.content.Context.DISPLAY_SERVICE; import static android.content.Context.WINDOW_SERVICE; import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; +import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import android.content.Context; import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. @@ -115,7 +116,9 @@ * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). + * (it's like opening a dialog on top of your activity). Creating a presentation on the main + * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown + * when invoking {@link #show()}. *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -188,12 +191,16 @@ public Presentation(Context outerContext, Display display, int theme) { mDisplay = display; mDisplayManager = (DisplayManager)getContext().getSystemService(DISPLAY_SERVICE); + final int windowType = + (display.getFlags() & Display.FLAG_PRIVATE) != 0 ? TYPE_PRIVATE_PRESENTATION + : TYPE_PRESENTATION; + final Window w = getWindow(); final WindowManager.LayoutParams attr = w.getAttributes(); attr.token = mToken; w.setAttributes(attr); w.setGravity(Gravity.FILL); - w.setType(TYPE_PRESENTATION); + w.setType(windowType); setCanceledOnTouchOutside(false); } @@ -242,7 +249,7 @@ protected void onStop() { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found. + * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. */ @Override public void show() { diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index b83b44d295b4..8af64b63681c 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -106,6 +106,7 @@ public class StatusBarManager { public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0; public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1; public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2; + public static final int CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE = 3; private Context mContext; private IStatusBarService mService; diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index db011dabac9e..c77cb82673fb 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -128,6 +128,8 @@ import android.os.Vibrator; import android.os.health.SystemHealthManager; import android.os.storage.StorageManager; +import android.pocket.IPocketService; +import android.pocket.PocketManager; import android.print.IPrintManager; import android.print.PrintManager; import android.service.oemlock.IOemLockService; @@ -781,6 +783,15 @@ public FingerprintManager createService(ContextImpl ctx) throws ServiceNotFoundE return new FingerprintManager(ctx.getOuterContext(), service); }}); + registerService(Context.POCKET_SERVICE, PocketManager.class, + new CachedServiceFetcher() { + @Override + public PocketManager createService(ContextImpl ctx) { + IBinder binder = ServiceManager.getService(Context.POCKET_SERVICE); + IPocketService service = IPocketService.Stub.asInterface(binder); + return new PocketManager(ctx.getOuterContext(), service); + }}); + registerService(Context.TV_INPUT_SERVICE, TvInputManager.class, new CachedServiceFetcher() { @Override diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index a81546dc1d47..5f62b96a0048 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -1882,7 +1882,7 @@ public static ComponentName getDefaultWallpaperComponent(Context context) { } if (cn == null) { - flat = context.getString(com.android.internal.R.string.default_wallpaper_component); + flat = context.getString(com.android.internal.R.string.default_wallpaper_component_custom); if (!TextUtils.isEmpty(flat)) { cn = ComponentName.unflattenFromString(flat); } diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index d1c957b8fedc..4cbba77df8b1 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -698,8 +698,11 @@ protected final void fullBackupFileTree(String packageName, String domain, Strin // Pull out the domain and set it aside to use when making the tarball. String domainPath = FullBackup.getBackupScheme(this).tokenToDirectoryPath(domain); if (domainPath == null) { - // Should never happen. - return; + if (startingPath == null) { + return; + } else { + domainPath = startingPath; + } } File rootFile = new File(startingPath); diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index ea9c9dab21ee..7b706b8a3895 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -152,10 +152,6 @@ public abstract class SliceProvider extends ContentProvider { * @hide */ public static final String EXTRA_PKG = "pkg"; - /** - * @hide - */ - public static final String EXTRA_PROVIDER_PKG = "provider_pkg"; /** * @hide */ @@ -355,7 +351,8 @@ public final String getType(Uri uri) { @Override public Bundle call(String method, String arg, Bundle extras) { if (method.equals(METHOD_SLICE)) { - Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); + Uri uri = getUriWithoutUserId(validateIncomingUriOrNull( + extras.getParcelable(EXTRA_BIND_URI))); List supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); String callingPackage = getCallingPackage(); @@ -369,7 +366,7 @@ public Bundle call(String method, String arg, Bundle extras) { } else if (method.equals(METHOD_MAP_INTENT)) { Intent intent = extras.getParcelable(EXTRA_INTENT); if (intent == null) return null; - Uri uri = onMapIntentToUri(intent); + Uri uri = validateIncomingUriOrNull(onMapIntentToUri(intent)); List supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); Bundle b = new Bundle(); if (uri != null) { @@ -383,24 +380,27 @@ public Bundle call(String method, String arg, Bundle extras) { } else if (method.equals(METHOD_MAP_ONLY_INTENT)) { Intent intent = extras.getParcelable(EXTRA_INTENT); if (intent == null) return null; - Uri uri = onMapIntentToUri(intent); + Uri uri = validateIncomingUriOrNull(onMapIntentToUri(intent)); Bundle b = new Bundle(); b.putParcelable(EXTRA_SLICE, uri); return b; } else if (method.equals(METHOD_PIN)) { - Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); + Uri uri = getUriWithoutUserId(validateIncomingUriOrNull( + extras.getParcelable(EXTRA_BIND_URI))); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Only the system can pin/unpin slices"); } handlePinSlice(uri); } else if (method.equals(METHOD_UNPIN)) { - Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); + Uri uri = getUriWithoutUserId(validateIncomingUriOrNull( + extras.getParcelable(EXTRA_BIND_URI))); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Only the system can pin/unpin slices"); } handleUnpinSlice(uri); } else if (method.equals(METHOD_GET_DESCENDANTS)) { - Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); + Uri uri = getUriWithoutUserId( + validateIncomingUriOrNull(extras.getParcelable(EXTRA_BIND_URI))); Bundle b = new Bundle(); b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS, new ArrayList<>(handleGetDescendants(uri))); @@ -416,6 +416,10 @@ public Bundle call(String method, String arg, Bundle extras) { return super.call(method, arg, extras); } + private Uri validateIncomingUriOrNull(Uri uri) { + return uri == null ? null : validateIncomingUri(uri); + } + private Collection handleGetDescendants(Uri uri) { mCallback = "onGetSliceDescendants"; return onGetSliceDescendants(uri); @@ -511,7 +515,6 @@ public static PendingIntent createPermissionIntent(Context context, Uri sliceUri "com.android.systemui.SlicePermissionActivity")); intent.putExtra(EXTRA_BIND_URI, sliceUri); intent.putExtra(EXTRA_PKG, callingPackage); - intent.putExtra(EXTRA_PROVIDER_PKG, context.getPackageName()); // Unique pending intent. intent.setData(sliceUri.buildUpon().appendQueryParameter("package", callingPackage) .build()); diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 44051081b595..74fdc63995d1 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -103,7 +103,7 @@ */ public final class BluetoothAdapter { private static final String TAG = "BluetoothAdapter"; - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean VDBG = false; /** @@ -644,6 +644,7 @@ public static synchronized BluetoothAdapter getDefaultAdapter() { * @throws IllegalArgumentException if address is invalid */ public BluetoothDevice getRemoteDevice(String address) { + android.util.SeempLog.record(62); return new BluetoothDevice(address); } @@ -659,6 +660,7 @@ public BluetoothDevice getRemoteDevice(String address) { * @throws IllegalArgumentException if address is invalid */ public BluetoothDevice getRemoteDevice(byte[] address) { + android.util.SeempLog.record(62); if (address == null || address.length != 6) { throw new IllegalArgumentException("Bluetooth address must have 6 bytes"); } @@ -890,6 +892,7 @@ public boolean enableBLE() { @RequiresPermission(Manifest.permission.BLUETOOTH) @AdapterState public int getState() { + android.util.SeempLog.record(63); int state = BluetoothAdapter.STATE_OFF; try { @@ -992,6 +995,7 @@ boolean getLeAccess() { */ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean enable() { + android.util.SeempLog.record(56); if (isEnabled()) { if (DBG) { Log.d(TAG, "enable(): BT already enabled!"); @@ -1029,6 +1033,7 @@ public boolean enable() { */ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean disable() { + android.util.SeempLog.record(57); try { return mManagerService.disable(ActivityThread.currentPackageName(), true); } catch (RemoteException e) { @@ -1047,6 +1052,7 @@ public boolean disable() { * @hide */ public boolean disable(boolean persist) { + android.util.SeempLog.record(57); try { return mManagerService.disable(ActivityThread.currentPackageName(), persist); @@ -1400,6 +1406,7 @@ public long getDiscoveryEndMillis() { */ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean startDiscovery() { + android.util.SeempLog.record(58); if (getState() != STATE_ON) { return false; } @@ -1795,6 +1802,7 @@ public void requestControllerActivityEnergyInfo(ResultReceiver result) { */ @RequiresPermission(Manifest.permission.BLUETOOTH) public Set getBondedDevices() { + android.util.SeempLog.record(61); if (getState() != STATE_ON) { return toDeviceSet(new BluetoothDevice[0]); } @@ -1887,6 +1895,7 @@ public int getConnectionState() { */ @RequiresPermission(Manifest.permission.BLUETOOTH) public int getProfileConnectionState(int profile) { + android.util.SeempLog.record(64); if (getState() != STATE_ON) { return BluetoothProfile.STATE_DISCONNECTED; } @@ -2017,6 +2026,7 @@ public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUI @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid) throws IOException { + android.util.SeempLog.record(59); return createNewRfcommSocketAndRecord(name, uuid, false, false); } diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index e3a6e064725e..5bbc15885356 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -61,6 +61,7 @@ public final class BluetoothCodecConfig implements Parcelable { public static final int CHANNEL_MODE_NONE = 0; public static final int CHANNEL_MODE_MONO = 0x1 << 0; public static final int CHANNEL_MODE_STEREO = 0x1 << 1; + public static final int CHANNEL_MODE_DUAL_CHANNEL = 0x1 << 2; private final int mCodecType; private int mCodecPriority; diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 3cf80746652e..8916b537ff29 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -894,7 +894,14 @@ public String getAlias() { return null; } try { - return service.getRemoteAlias(this); + String alias = service.getRemoteAlias(this); + if (alias == null) { + return getName(); + } + return alias + .replace('\t', ' ') + .replace('\n', ' ') + .replace('\r', ' '); } catch (RemoteException e) { Log.e(TAG, "", e); } diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java index 3bc8544ebf87..c5e61e03701c 100644 --- a/core/java/android/bluetooth/BluetoothHidDevice.java +++ b/core/java/android/bluetooth/BluetoothHidDevice.java @@ -463,13 +463,11 @@ boolean doBind() { } void doUnbind() { - if (mService != null) { - mService = null; - try { - mContext.unbindService(mConnection); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to unbind HidDevService", e); - } + mService = null; + try { + mContext.unbindService(mConnection); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unable to unbind HidDevService", e); } } diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java index f8aaba910b7b..d85540adf6ac 100644 --- a/core/java/android/bluetooth/le/ScanRecord.java +++ b/core/java/android/bluetooth/le/ScanRecord.java @@ -101,6 +101,9 @@ public SparseArray getManufacturerSpecificData() { */ @Nullable public byte[] getManufacturerSpecificData(int manufacturerId) { + if (mManufacturerSpecificData == null) { + return null; + } return mManufacturerSpecificData.get(manufacturerId); } diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index a061e610fd40..83e14b5ce8a7 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -708,6 +708,7 @@ public void appNotRespondingViaProvider(IContentProvider icp) { public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { + android.util.SeempLog.record_uri(13, uri); return query(uri, projection, selection, selectionArgs, sortOrder, null); } @@ -783,6 +784,7 @@ public void appNotRespondingViaProvider(IContentProvider icp) { public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri, @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) { + android.util.SeempLog.record_uri(13, uri); Preconditions.checkNotNull(uri, "uri"); IContentProvider unstableProvider = acquireUnstableProvider(uri); if (unstableProvider == null) { @@ -1578,6 +1580,7 @@ public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException */ public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url, @Nullable ContentValues values) { + android.util.SeempLog.record_uri(37, url); Preconditions.checkNotNull(url, "url"); IContentProvider provider = acquireProvider(url); if (provider == null) { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9a7c575a3b1b..bcbf34867eef 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4218,6 +4218,16 @@ public abstract boolean startInstrumentation(@NonNull ComponentName className, @SystemApi public static final String SECURE_ELEMENT_SERVICE = "secure_element"; + /** + * Use with {@link #getSystemService} to retrieve a + * {@link android.os.PocketManager} for accessing and listening to device pocket state. + * + * @hide + * @see #getSystemService + * @see android.os.PocketManager + */ + public static final String POCKET_SERVICE = "pocket"; + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index e4502ffdd61f..e32ddc7fef1a 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2362,6 +2362,18 @@ public static Intent createChooser(Intent target, CharSequence title, IntentSend @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; + /** + * Broadcast Action: Sent to the optional package verifier when a package + * needs to be verified. The data contains the package URI. + *

+ * This is a protected intent. + *

+ * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_NEEDS_OPTIONAL_VERIFICATION = "com.qualcomm.qti.intent.action.PACKAGE_NEEDS_OPTIONAL_VERIFICATION"; + /** * Broadcast Action: Sent to the system package verifier when a package is * verified. The data contains the package URI. @@ -2884,6 +2896,21 @@ public static Intent createChooser(Intent target, CharSequence title, IntentSend @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE"; + /** + *

Broadcast Action: The user has changed carrier label:

+ *
    + *
  • state - String value.
  • + *
+ * + *

This is a protected intent that can only be sent + * by the system. + * + * @hide + */ + //@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_CUSTOM_CARRIER_LABEL_CHANGED + = "android.intent.action.CUSTOM_CARRIER_LABEL"; + /** * Broadcast Action: Some content providers have parts of their namespace * where they publish new events or items that the user may be especially @@ -10240,6 +10267,7 @@ public void prepareToLeaveProcess(boolean leavingPackage) { case ACTION_MEDIA_SCANNER_FINISHED: case ACTION_MEDIA_SCANNER_SCAN_FILE: case ACTION_PACKAGE_NEEDS_VERIFICATION: + case ACTION_PACKAGE_NEEDS_OPTIONAL_VERIFICATION: case ACTION_PACKAGE_VERIFIED: // Ignore legacy actions break; diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl index 5b3c9dd93370..0ed88e02d536 100644 --- a/core/java/android/content/om/IOverlayManager.aidl +++ b/core/java/android/content/om/IOverlayManager.aidl @@ -150,4 +150,7 @@ interface IOverlayManager { * @param userId The user for which to change the overlay. */ boolean setLowestPriority(in String packageName, in int userId); + + void reloadAssets(in String packageName, in int userId); + void reloadAndroidAssets(in int userId); } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 25af1a76700f..b51fa6fc2b29 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1635,6 +1635,7 @@ public long getSize() { /** * Get the value set in {@link SessionParams#setOriginatingUri(Uri)}. + * Note: This value will only be non-null for the owner of the session. */ public @Nullable Uri getOriginatingUri() { return originatingUri; @@ -1649,6 +1650,7 @@ public int getOriginatingUid() { /** * Get the value set in {@link SessionParams#setReferrerUri(Uri)} + * Note: This value will only be non-null for the owner of the session. */ public @Nullable Uri getReferrerUri() { return referrerUri; diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java index 52e28a4b4b9b..d676cde9005d 100644 --- a/core/java/android/content/pm/PackageItemInfo.java +++ b/core/java/android/content/pm/PackageItemInfo.java @@ -93,7 +93,7 @@ public class PackageItemInfo { private static final float MAX_LABEL_SIZE_PX = 500f; /** The maximum length of a safe label, in characters */ - private static final int MAX_SAFE_LABEL_LENGTH = 50000; + private static final int MAX_SAFE_LABEL_LENGTH = 1000; private static volatile boolean sForceSafeLabels = false; @@ -191,7 +191,9 @@ public PackageItemInfo(PackageItemInfo orig) { if (sForceSafeLabels) { return loadSafeLabel(pm); } else { - return loadUnsafeLabel(pm); + // Trims the label string to the MAX_SAFE_LABEL_LENGTH. This is to prevent that the + // system is overwhelmed by an enormous string returned by the application. + return TextUtils.trimToSize(loadUnsafeLabel(pm), MAX_SAFE_LABEL_LENGTH); } } diff --git a/core/java/android/content/res/AccentUtils.java b/core/java/android/content/res/AccentUtils.java new file mode 100644 index 000000000000..0e7fae6285cc --- /dev/null +++ b/core/java/android/content/res/AccentUtils.java @@ -0,0 +1,40 @@ +package android.content.res; + +import android.graphics.Color; +import android.os.SystemProperties; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; + +public class AccentUtils { + private static ArrayList accentResources = new ArrayList<>( + Arrays.asList("user_icon_1", + "accent_device_default_700", + "accent_device_default_light", + "accent_device_default_dark")); + + private static final String ACCENT_COLOR_PROP = "persist.sys.theme.accentcolor"; + + private static final String TAG = "AccentUtils"; + + static boolean isResourceAccent(String resName) { + for (String ar : accentResources) + if (resName.contains(ar)) + return true; + return false; + } + + public static int getAccentColor(int defaultColor) { + try { + String colorValue = SystemProperties.get(ACCENT_COLOR_PROP, "-1"); + return "-1".equals(colorValue) + ? defaultColor + : Color.parseColor("#" + colorValue); + } catch (Exception e) { + Log.e(TAG, "Failed to set accent: " + e.getMessage() + + "\nSetting default: " + defaultColor); + return defaultColor; + } + } +} diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 289534273d13..4ddaa9b4cdf8 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1050,8 +1050,11 @@ protected void finalize() throws Throwable { } } - if (mObject != 0) { - nativeDestroy(mObject); + synchronized (this) { + if (mObject != 0) { + nativeDestroy(mObject); + mObject = 0; + } } } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 7adea6a880be..32bf24ddf66c 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -961,6 +961,8 @@ public int getColor(@ColorRes int id, @Nullable Theme theme) throws NotFoundExce impl.getValue(id, value, true); if (value.type >= TypedValue.TYPE_FIRST_INT && value.type <= TypedValue.TYPE_LAST_INT) { + if (AccentUtils.isResourceAccent(getResourceName(id))) + value.data = AccentUtils.getAccentColor(value.data); return value.data; } else if (value.type != TypedValue.TYPE_STRING) { throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id) diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 8c980677fdd0..de725023f8cc 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -626,6 +626,13 @@ Drawable loadDrawable(@NonNull Resources wrapper, @NonNull TypedValue value, int } dr = cs.newDrawable(wrapper); } else if (isColorDrawable) { + try { + if (AccentUtils.isResourceAccent(getResourceName(id))) + value.data = AccentUtils.getAccentColor(value.data); + } catch (NotFoundException nfe) { + } catch (Exception ex) { + Log.e(TAG, ex.getMessage()); + } dr = new ColorDrawable(value.data); } else { dr = loadDrawableForCookie(wrapper, value, id, density); @@ -984,6 +991,14 @@ ComplexColor loadComplexColor(Resources wrapper, @NonNull TypedValue value, int final long key = (((long) value.assetCookie) << 32) | value.data; + try { + if (AccentUtils.isResourceAccent(getResourceName(id))) + value.data = AccentUtils.getAccentColor(value.data); + } catch (NotFoundException nfe) { + } catch (Exception ex) { + Log.e(TAG, ex.getMessage()); + } + // Handle inline color definitions. if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) { @@ -1024,6 +1039,14 @@ ColorStateList loadColorStateList(Resources wrapper, TypedValue value, int id, } } + try { + if (AccentUtils.isResourceAccent(getResourceName(id))) + value.data = AccentUtils.getAccentColor(value.data); + } catch (NotFoundException nfe) { + } catch (Exception ex) { + Log.e(TAG, ex.getMessage()); + } + final long key = (((long) value.assetCookie) << 32) | value.data; // Handle inline color definitions. diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index cbb3c6df0558..3e08a1e1a4a8 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -22,11 +22,13 @@ import android.annotation.StyleableRes; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; +import android.content.res.Resources.NotFoundException; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.StrictMode; import android.util.AttributeSet; import android.util.DisplayMetrics; +import android.util.Log; import android.util.TypedValue; import com.android.internal.util.XmlUtils; @@ -46,6 +48,8 @@ */ public class TypedArray { + private static final String TAG = "TypedArray"; + static TypedArray obtain(Resources res, int len) { TypedArray attrs = res.mTypedArrayPool.acquire(); if (attrs == null) { @@ -458,6 +462,21 @@ public int getColor(@StyleableRes int index, @ColorInt int defValue) { final int[] data = mData; final int type = data[index + STYLE_TYPE]; + + try { + int resId = data[index + 3]; + if (resId > 0) { + if (AccentUtils.isResourceAccent(this.mAssets.getResourceName(resId))) { + int newColor = AccentUtils.getAccentColor(defValue); + if (newColor != defValue) + return newColor; + } + } + } catch (NotFoundException nfe) { + } catch (Exception ex) { + Log.e(TAG, ex.getMessage()); + } + if (type == TypedValue.TYPE_NULL) { return defValue; } else if (type >= TypedValue.TYPE_FIRST_INT diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java index 442e4cf0110c..7bd26b6d048c 100644 --- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java +++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java @@ -28,14 +28,19 @@ import android.text.TextUtils; import android.util.Log; +import com.android.internal.util.ArrayUtils; + import libcore.util.EmptyArray; import java.util.Arrays; import java.util.Iterator; +import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; +import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -45,15 +50,24 @@ public class SQLiteQueryBuilder { private static final String TAG = "SQLiteQueryBuilder"; - private static final Pattern sLimitPattern = - Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?"); private Map mProjectionMap = null; + + private static final Pattern sAggregationPattern = Pattern.compile( + "(?i)(AVG|COUNT|MAX|MIN|SUM|TOTAL|GROUP_CONCAT)\\((.+)\\)"); + + private List mProjectionGreylist = null; + private String mTables = ""; private StringBuilder mWhereClause = null; // lazily created private boolean mDistinct; private SQLiteDatabase.CursorFactory mFactory; - private boolean mStrict; + + private static final int STRICT_PARENTHESES = 1 << 0; + private static final int STRICT_COLUMNS = 1 << 1; + private static final int STRICT_GRAMMAR = 1 << 2; + + private int mStrictFlags; public SQLiteQueryBuilder() { mDistinct = false; @@ -138,6 +152,37 @@ public void setProjectionMap(Map columnMap) { mProjectionMap = columnMap; } + /** + * Gets the projection map for the query, as last configured by + * {@link #setProjectionMap(Map)}. + * + * @hide + */ + public @Nullable Map getProjectionMap() { + return mProjectionMap; + } + + /** + * Sets a projection greylist of columns that will be allowed through, even + * when {@link #setStrict(boolean)} is enabled. This provides a way for + * abusive custom columns like {@code COUNT(*)} to continue working. + * + * @hide + */ + public void setProjectionGreylist(@Nullable List projectionGreylist) { + mProjectionGreylist = projectionGreylist; + } + + /** + * Gets the projection greylist for the query, as last configured by + * {@link #setProjectionGreylist(List)}. + * + * @hide + */ + public @Nullable List getProjectionGreylist() { + return mProjectionGreylist; + } + /** * Sets the cursor factory to be used for the query. You can use * one factory for all queries on a database but it is normally @@ -170,8 +215,90 @@ public void setCursorFactory(SQLiteDatabase.CursorFactory factory) { * * By default, this value is false. */ - public void setStrict(boolean flag) { - mStrict = flag; + public void setStrict(boolean strict) { + if (strict) { + mStrictFlags |= STRICT_PARENTHESES; + } else { + mStrictFlags &= ~STRICT_PARENTHESES; + } + } + + /** + * Get if the query is marked as strict, as last configured by + * {@link #setStrict(boolean)}. + * + * @hide + */ + public boolean isStrict() { + return (mStrictFlags & STRICT_PARENTHESES) != 0; + } + + /** + * When enabled, verify that all projections and {@link ContentValues} only + * contain valid columns as defined by {@link #setProjectionMap(Map)}. + *

+ * This enforcement applies to {@link #insert}, {@link #query}, and + * {@link #update} operations. Any enforcement failures will throw an + * {@link IllegalArgumentException}. + * + * @hide + */ + public void setStrictColumns(boolean strictColumns) { + if (strictColumns) { + mStrictFlags |= STRICT_COLUMNS; + } else { + mStrictFlags &= ~STRICT_COLUMNS; + } + } + + /** + * Get if the query is marked as strict, as last configured by + * {@link #setStrictColumns(boolean)}. + * + * @hide + */ + public boolean isStrictColumns() { + return (mStrictFlags & STRICT_COLUMNS) != 0; + } + + /** + * When enabled, verify that all untrusted SQL conforms to a restricted SQL + * grammar. Here are the restrictions applied: + *

    + *
  • In {@code WHERE} and {@code HAVING} clauses: subqueries, raising, and + * windowing terms are rejected. + *
  • In {@code GROUP BY} clauses: only valid columns are allowed. + *
  • In {@code ORDER BY} clauses: only valid columns, collation, and + * ordering terms are allowed. + *
  • In {@code LIMIT} clauses: only numerical values and offset terms are + * allowed. + *
+ * All column references must be valid as defined by + * {@link #setProjectionMap(Map)}. + *

+ * This enforcement applies to {@link #query}, {@link #update} and + * {@link #delete} operations. This enforcement does not apply to trusted + * inputs, such as those provided by {@link #appendWhere}. Any enforcement + * failures will throw an {@link IllegalArgumentException}. + * + * @hide + */ + public void setStrictGrammar(boolean strictGrammar) { + if (strictGrammar) { + mStrictFlags |= STRICT_GRAMMAR; + } else { + mStrictFlags &= ~STRICT_GRAMMAR; + } + } + + /** + * Get if the query is marked as strict, as last configured by + * {@link #setStrictGrammar(boolean)}. + * + * @hide + */ + public boolean isStrictGrammar() { + return (mStrictFlags & STRICT_GRAMMAR) != 0; } /** @@ -207,9 +334,6 @@ public static String buildQueryString( throw new IllegalArgumentException( "HAVING clauses are only permitted when using a groupBy clause"); } - if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) { - throw new IllegalArgumentException("invalid LIMIT clauses:" + limit); - } StringBuilder query = new StringBuilder(120); @@ -383,7 +507,13 @@ public Cursor query(SQLiteDatabase db, String[] projectionIn, projectionIn, selection, groupBy, having, sortOrder, limit); - if (mStrict && selection != null && selection.length() > 0) { + if (isStrictColumns()) { + enforceStrictColumns(projectionIn); + } + if (isStrictGrammar()) { + enforceStrictGrammar(selection, groupBy, having, sortOrder, limit); + } + if (isStrict()) { // Validate the user-supplied selection to detect syntactic anomalies // in the selection string that could indicate a SQL injection attempt. // The idea is to ensure that the selection clause is a valid SQL expression @@ -401,7 +531,7 @@ public Cursor query(SQLiteDatabase db, String[] projectionIn, // Execute wrapped query for extra protection final String wrappedSql = buildQuery(projectionIn, wrap(selection), groupBy, - having, sortOrder, limit); + wrap(having), sortOrder, limit); sql = wrappedSql; } else { // Execute unwrapped query @@ -446,7 +576,13 @@ public int update(@NonNull SQLiteDatabase db, @NonNull ContentValues values, final String sql; final String unwrappedSql = buildUpdate(values, selection); - if (mStrict) { + if (isStrictColumns()) { + enforceStrictColumns(values); + } + if (isStrictGrammar()) { + enforceStrictGrammar(selection, null, null, null, null); + } + if (isStrict()) { // Validate the user-supplied selection to detect syntactic anomalies // in the selection string that could indicate a SQL injection attempt. // The idea is to ensure that the selection clause is a valid SQL expression @@ -516,7 +652,10 @@ public int delete(@NonNull SQLiteDatabase db, @Nullable String selection, final String sql; final String unwrappedSql = buildDelete(selection); - if (mStrict) { + if (isStrictGrammar()) { + enforceStrictGrammar(selection, null, null, null, null); + } + if (isStrict()) { // Validate the user-supplied selection to detect syntactic anomalies // in the selection string that could indicate a SQL injection attempt. // The idea is to ensure that the selection clause is a valid SQL expression @@ -551,6 +690,82 @@ public int delete(@NonNull SQLiteDatabase db, @Nullable String selection, return db.executeSql(sql, sqlArgs); } + private void enforceStrictColumns(@Nullable String[] projection) { + Objects.requireNonNull(mProjectionMap, "No projection map defined"); + + computeProjection(projection); + } + + private void enforceStrictColumns(@NonNull ContentValues values) { + Objects.requireNonNull(mProjectionMap, "No projection map defined"); + + final Set rawValues = values.keySet(); + final Iterator rawValuesIt = rawValues.iterator(); + while (rawValuesIt.hasNext()) { + final String column = rawValuesIt.next(); + if (!mProjectionMap.containsKey(column)) { + throw new IllegalArgumentException("Invalid column " + column); + } + } + } + + private void enforceStrictGrammar(@Nullable String selection, @Nullable String groupBy, + @Nullable String having, @Nullable String sortOrder, @Nullable String limit) { + SQLiteTokenizer.tokenize(selection, SQLiteTokenizer.OPTION_NONE, + this::enforceStrictGrammarWhereHaving); + SQLiteTokenizer.tokenize(groupBy, SQLiteTokenizer.OPTION_NONE, + this::enforceStrictGrammarGroupBy); + SQLiteTokenizer.tokenize(having, SQLiteTokenizer.OPTION_NONE, + this::enforceStrictGrammarWhereHaving); + SQLiteTokenizer.tokenize(sortOrder, SQLiteTokenizer.OPTION_NONE, + this::enforceStrictGrammarOrderBy); + SQLiteTokenizer.tokenize(limit, SQLiteTokenizer.OPTION_NONE, + this::enforceStrictGrammarLimit); + } + + private void enforceStrictGrammarWhereHaving(@NonNull String token) { + if (isTableOrColumn(token)) return; + if (SQLiteTokenizer.isFunction(token)) return; + if (SQLiteTokenizer.isType(token)) return; + + // NOTE: we explicitly don't allow SELECT subqueries, since they could + // leak data that should have been filtered by the trusted where clause + switch (token.toUpperCase(Locale.US)) { + case "AND": case "AS": case "BETWEEN": case "BINARY": + case "CASE": case "CAST": case "COLLATE": case "DISTINCT": + case "ELSE": case "END": case "ESCAPE": case "EXISTS": + case "GLOB": case "IN": case "IS": case "ISNULL": + case "LIKE": case "MATCH": case "NOCASE": case "NOT": + case "NOTNULL": case "NULL": case "OR": case "REGEXP": + case "RTRIM": case "THEN": case "WHEN": + return; + } + throw new IllegalArgumentException("Invalid token " + token); + } + + private void enforceStrictGrammarGroupBy(@NonNull String token) { + if (isTableOrColumn(token)) return; + throw new IllegalArgumentException("Invalid token " + token); + } + + private void enforceStrictGrammarOrderBy(@NonNull String token) { + if (isTableOrColumn(token)) return; + switch (token.toUpperCase(Locale.US)) { + case "COLLATE": case "ASC": case "DESC": + case "BINARY": case "RTRIM": case "NOCASE": + return; + } + throw new IllegalArgumentException("Invalid token " + token); + } + + private void enforceStrictGrammarLimit(@NonNull String token) { + switch (token.toUpperCase(Locale.US)) { + case "OFFSET": + return; + } + throw new IllegalArgumentException("Invalid token " + token); + } + /** * Construct a SELECT statement suitable for use in a group of * SELECT statements that will be joined through UNION operators @@ -611,7 +826,7 @@ public String buildUpdate(ContentValues values, String selection) { StringBuilder sql = new StringBuilder(120); sql.append("UPDATE "); - sql.append(mTables); + sql.append(SQLiteDatabase.findEditTable(mTables)); sql.append(" SET "); final String[] rawKeys = values.keySet().toArray(EmptyArray.STRING); @@ -632,7 +847,7 @@ public String buildUpdate(ContentValues values, String selection) { public String buildDelete(String selection) { StringBuilder sql = new StringBuilder(120); sql.append("DELETE FROM "); - sql.append(mTables); + sql.append(SQLiteDatabase.findEditTable(mTables)); final String where = computeWhere(selection); appendClause(sql, " WHERE ", where); @@ -763,35 +978,23 @@ public String buildUnionQuery(String[] subQueries, String sortOrder, String limi return query.toString(); } - private String[] computeProjection(String[] projectionIn) { - if (projectionIn != null && projectionIn.length > 0) { - if (mProjectionMap != null) { - String[] projection = new String[projectionIn.length]; - int length = projectionIn.length; - - for (int i = 0; i < length; i++) { - String userColumn = projectionIn[i]; - String column = mProjectionMap.get(userColumn); - - if (column != null) { - projection[i] = column; - continue; - } - - if (!mStrict && - ( userColumn.contains(" AS ") || userColumn.contains(" as "))) { - /* A column alias already exist */ - projection[i] = userColumn; - continue; - } + private static @NonNull String maybeWithOperator(@Nullable String operator, + @NonNull String column) { + if (operator != null) { + return operator + "(" + column + ")"; + } else { + return column; + } + } - throw new IllegalArgumentException("Invalid column " - + projectionIn[i]); - } - return projection; - } else { - return projectionIn; + /** {@hide} */ + public @Nullable String[] computeProjection(@Nullable String[] projectionIn) { + if (!ArrayUtils.isEmpty(projectionIn)) { + String[] projectionOut = new String[projectionIn.length]; + for (int i = 0; i < projectionIn.length; i++) { + projectionOut[i] = computeSingleProjectionOrThrow(projectionIn[i]); } + return projectionOut; } else if (mProjectionMap != null) { // Return all columns in projection map. Set> entrySet = mProjectionMap.entrySet(); @@ -813,7 +1016,71 @@ private String[] computeProjection(String[] projectionIn) { return null; } - private @Nullable String computeWhere(@Nullable String selection) { + private @NonNull String computeSingleProjectionOrThrow(@NonNull String userColumn) { + final String column = computeSingleProjection(userColumn); + if (column != null) { + return column; + } else { + throw new IllegalArgumentException("Invalid column " + userColumn); + } + } + + private @Nullable String computeSingleProjection(@NonNull String userColumn) { + // When no mapping provided, anything goes + if (mProjectionMap == null) { + return userColumn; + } + + String operator = null; + String column = mProjectionMap.get(userColumn); + + // When no direct match found, look for aggregation + if (column == null) { + final Matcher matcher = sAggregationPattern.matcher(userColumn); + if (matcher.matches()) { + operator = matcher.group(1); + userColumn = matcher.group(2); + column = mProjectionMap.get(userColumn); + } + } + + if (column != null) { + return maybeWithOperator(operator, column); + } + + if (mStrictFlags == 0 + && (userColumn.contains(" AS ") || userColumn.contains(" as "))) { + /* A column alias already exist */ + return maybeWithOperator(operator, userColumn); + } + + // If greylist is configured, we might be willing to let + // this custom column bypass our strict checks. + if (mProjectionGreylist != null) { + boolean match = false; + for (Pattern p : mProjectionGreylist) { + if (p.matcher(userColumn).matches()) { + match = true; + break; + } + } + + if (match) { + Log.w(TAG, "Allowing abusive custom column: " + userColumn); + return maybeWithOperator(operator, userColumn); + } + } + + return null; + } + + private boolean isTableOrColumn(String token) { + if (mTables.equals(token)) return true; + return computeSingleProjection(token) != null; + } + + /** {@hide} */ + public @Nullable String computeWhere(@Nullable String selection) { final boolean hasInternal = !TextUtils.isEmpty(mWhereClause); final boolean hasExternal = !TextUtils.isEmpty(selection); diff --git a/core/java/android/database/sqlite/SQLiteTokenizer.java b/core/java/android/database/sqlite/SQLiteTokenizer.java new file mode 100644 index 000000000000..7e7c3fb976c7 --- /dev/null +++ b/core/java/android/database/sqlite/SQLiteTokenizer.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.database.sqlite; + +import android.annotation.NonNull; +import android.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.function.Consumer; + +/** + * SQL Tokenizer specialized to extract tokens from SQL (snippets). + *

+ * Based on sqlite3GetToken() in tokenzie.c in SQLite. + *

+ * Source for v3.8.6 (which android uses): http://www.sqlite.org/src/artifact/ae45399d6252b4d7 + * (Latest source as of now: http://www.sqlite.org/src/artifact/78c8085bc7af1922) + *

+ * Also draft spec: http://www.sqlite.org/draft/tokenreq.html + * + * @hide + */ +public class SQLiteTokenizer { + private static boolean isAlpha(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_'); + } + + private static boolean isNum(char ch) { + return ('0' <= ch && ch <= '9'); + } + + private static boolean isAlNum(char ch) { + return isAlpha(ch) || isNum(ch); + } + + private static boolean isAnyOf(char ch, String set) { + return set.indexOf(ch) >= 0; + } + + private static IllegalArgumentException genException(String message, String sql) { + throw new IllegalArgumentException(message + " in '" + sql + "'"); + } + + private static char peek(String s, int index) { + return index < s.length() ? s.charAt(index) : '\0'; + } + + public static final int OPTION_NONE = 0; + + /** + * Require that SQL contains only tokens; any comments or values will result + * in an exception. + */ + public static final int OPTION_TOKEN_ONLY = 1 << 0; + + /** + * Tokenize the given SQL, returning the list of each encountered token. + * + * @throws IllegalArgumentException if invalid SQL is encountered. + */ + public static List tokenize(@Nullable String sql, int options) { + final ArrayList res = new ArrayList<>(); + tokenize(sql, options, res::add); + return res; + } + + /** + * Tokenize the given SQL, sending each encountered token to the given + * {@link Consumer}. + * + * @throws IllegalArgumentException if invalid SQL is encountered. + */ + public static void tokenize(@Nullable String sql, int options, Consumer checker) { + if (sql == null) { + return; + } + int pos = 0; + final int len = sql.length(); + while (pos < len) { + final char ch = peek(sql, pos); + + // Regular token. + if (isAlpha(ch)) { + final int start = pos; + pos++; + while (isAlNum(peek(sql, pos))) { + pos++; + } + final int end = pos; + + final String token = sql.substring(start, end); + checker.accept(token); + + continue; + } + + // Handle quoted tokens + if (isAnyOf(ch, "'\"`")) { + final int quoteStart = pos; + pos++; + + for (;;) { + pos = sql.indexOf(ch, pos); + if (pos < 0) { + throw genException("Unterminated quote", sql); + } + if (peek(sql, pos + 1) != ch) { + break; + } + // Quoted quote char -- e.g. "abc""def" is a single string. + pos += 2; + } + final int quoteEnd = pos; + pos++; + + if (ch != '\'') { + // Extract the token + final String tokenUnquoted = sql.substring(quoteStart + 1, quoteEnd); + + final String token; + + // Unquote if needed. i.e. "aa""bb" -> aa"bb + if (tokenUnquoted.indexOf(ch) >= 0) { + token = tokenUnquoted.replaceAll( + String.valueOf(ch) + ch, String.valueOf(ch)); + } else { + token = tokenUnquoted; + } + checker.accept(token); + } else { + if ((options &= OPTION_TOKEN_ONLY) != 0) { + throw genException("Non-token detected", sql); + } + } + continue; + } + // Handle tokens enclosed in [...] + if (ch == '[') { + final int quoteStart = pos; + pos++; + + pos = sql.indexOf(']', pos); + if (pos < 0) { + throw genException("Unterminated quote", sql); + } + final int quoteEnd = pos; + pos++; + + final String token = sql.substring(quoteStart + 1, quoteEnd); + + checker.accept(token); + continue; + } + if ((options &= OPTION_TOKEN_ONLY) != 0) { + throw genException("Non-token detected", sql); + } + + // Detect comments. + if (ch == '-' && peek(sql, pos + 1) == '-') { + pos += 2; + pos = sql.indexOf('\n', pos); + if (pos < 0) { + // We disallow strings ending in an inline comment. + throw genException("Unterminated comment", sql); + } + pos++; + + continue; + } + if (ch == '/' && peek(sql, pos + 1) == '*') { + pos += 2; + pos = sql.indexOf("*/", pos); + if (pos < 0) { + throw genException("Unterminated comment", sql); + } + pos += 2; + + continue; + } + + // Semicolon is never allowed. + if (ch == ';') { + throw genException("Semicolon is not allowed", sql); + } + + // For this purpose, we can simply ignore other characters. + // (Note it doesn't handle the X'' literal properly and reports this X as a token, + // but that should be fine...) + pos++; + } + } + + /** + * Test if given token is a + * SQLite reserved + * keyword. + */ + public static boolean isKeyword(@NonNull String token) { + switch (token.toUpperCase(Locale.US)) { + case "ABORT": case "ACTION": case "ADD": case "AFTER": + case "ALL": case "ALTER": case "ANALYZE": case "AND": + case "AS": case "ASC": case "ATTACH": case "AUTOINCREMENT": + case "BEFORE": case "BEGIN": case "BETWEEN": case "BINARY": + case "BY": case "CASCADE": case "CASE": case "CAST": + case "CHECK": case "COLLATE": case "COLUMN": case "COMMIT": + case "CONFLICT": case "CONSTRAINT": case "CREATE": case "CROSS": + case "CURRENT": case "CURRENT_DATE": case "CURRENT_TIME": case "CURRENT_TIMESTAMP": + case "DATABASE": case "DEFAULT": case "DEFERRABLE": case "DEFERRED": + case "DELETE": case "DESC": case "DETACH": case "DISTINCT": + case "DO": case "DROP": case "EACH": case "ELSE": + case "END": case "ESCAPE": case "EXCEPT": case "EXCLUDE": + case "EXCLUSIVE": case "EXISTS": case "EXPLAIN": case "FAIL": + case "FILTER": case "FOLLOWING": case "FOR": case "FOREIGN": + case "FROM": case "FULL": case "GLOB": case "GROUP": + case "GROUPS": case "HAVING": case "IF": case "IGNORE": + case "IMMEDIATE": case "IN": case "INDEX": case "INDEXED": + case "INITIALLY": case "INNER": case "INSERT": case "INSTEAD": + case "INTERSECT": case "INTO": case "IS": case "ISNULL": + case "JOIN": case "KEY": case "LEFT": case "LIKE": + case "LIMIT": case "MATCH": case "NATURAL": case "NO": + case "NOCASE": case "NOT": case "NOTHING": case "NOTNULL": + case "NULL": case "OF": case "OFFSET": case "ON": + case "OR": case "ORDER": case "OTHERS": case "OUTER": + case "OVER": case "PARTITION": case "PLAN": case "PRAGMA": + case "PRECEDING": case "PRIMARY": case "QUERY": case "RAISE": + case "RANGE": case "RECURSIVE": case "REFERENCES": case "REGEXP": + case "REINDEX": case "RELEASE": case "RENAME": case "REPLACE": + case "RESTRICT": case "RIGHT": case "ROLLBACK": case "ROW": + case "ROWS": case "RTRIM": case "SAVEPOINT": case "SELECT": + case "SET": case "TABLE": case "TEMP": case "TEMPORARY": + case "THEN": case "TIES": case "TO": case "TRANSACTION": + case "TRIGGER": case "UNBOUNDED": case "UNION": case "UNIQUE": + case "UPDATE": case "USING": case "VACUUM": case "VALUES": + case "VIEW": case "VIRTUAL": case "WHEN": case "WHERE": + case "WINDOW": case "WITH": case "WITHOUT": + return true; + default: + return false; + } + } + + /** + * Test if given token is a + * SQLite reserved + * function. + */ + public static boolean isFunction(@NonNull String token) { + switch (token.toLowerCase(Locale.US)) { + case "abs": case "avg": case "char": case "coalesce": + case "count": case "glob": case "group_concat": case "hex": + case "ifnull": case "instr": case "length": case "like": + case "likelihood": case "likely": case "lower": case "ltrim": + case "max": case "min": case "nullif": case "random": + case "randomblob": case "replace": case "round": case "rtrim": + case "substr": case "sum": case "total": case "trim": + case "typeof": case "unicode": case "unlikely": case "upper": + case "zeroblob": + return true; + default: + return false; + } + } + + /** + * Test if given token is a + * SQLite reserved type. + */ + public static boolean isType(@NonNull String token) { + switch (token.toUpperCase(Locale.US)) { + case "INT": case "INTEGER": case "TINYINT": case "SMALLINT": + case "MEDIUMINT": case "BIGINT": case "INT2": case "INT8": + case "CHARACTER": case "VARCHAR": case "NCHAR": case "NVARCHAR": + case "TEXT": case "CLOB": case "BLOB": case "REAL": + case "DOUBLE": case "FLOAT": case "NUMERIC": case "DECIMAL": + case "BOOLEAN": case "DATE": case "DATETIME": + return true; + default: + return false; + } + } +} diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index d17223671ed5..78246c4f5e18 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -37,6 +37,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemProperties; import android.renderscript.Allocation; import android.renderscript.Element; import android.renderscript.RSIllegalArgumentException; @@ -46,6 +47,7 @@ import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; +import android.os.SystemProperties; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsCallback; @@ -163,6 +165,10 @@ public class Camera { private static final int CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x200; private static final int CAMERA_MSG_PREVIEW_METADATA = 0x400; private static final int CAMERA_MSG_FOCUS_MOVE = 0x800; + /* ### QC ADD-ONS: START */ + private static final int CAMERA_MSG_STATS_DATA = 0x1000; + private static final int CAMERA_MSG_META_DATA = 0x2000; + /* ### QC ADD-ONS: END */ private long mNativeContext; // accessed by native methods private EventHandler mEventHandler; @@ -193,6 +199,17 @@ public class Camera { private boolean mShutterSoundEnabledFromApp = true; private static final int NO_ERROR = 0; + private static final int EACCESS = -13; + private static final int ENODEV = -19; + private static final int EBUSY = -16; + private static final int EINVAL = -22; + private static final int ENOSYS = -38; + private static final int EUSERS = -87; + private static final int EOPNOTSUPP = -95; + /* ### QC ADD-ONS: START */ + private CameraDataCallback mCameraDataCallback; + private CameraMetaDataCallback mCameraMetaDataCallback; + /* ### QC ADD-ONS: END */ /** * Broadcast Action: A new picture is taken by the camera, and the entry of @@ -273,7 +290,47 @@ public class Camera { * @return total number of accessible camera devices, or 0 if there are no * cameras or an error was encountered enumerating them. */ - public native static int getNumberOfCameras(); + public static int getNumberOfCameras() { + boolean exposeAuxCamera = true; + String packageName = ActivityThread.currentOpPackageName(); + /* Force to expose only two cameras + * if the package name does not falls in this bucket + */ + String packageList = SystemProperties.get("vendor.camera.aux.packagelist"); + String packageBlacklist = SystemProperties.get("vendor.camera.aux.packageblacklist"); + if (packageList.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageList); + exposeAuxCamera = false; + for (String str : splitter) { + if (packageName.equals(str)) { + exposeAuxCamera = true; + break; + } + } + } else if (packageBlacklist.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageBlacklist); + exposeAuxCamera = true; + for (String str : splitter) { + if (packageName.equals(str)) { + exposeAuxCamera = false; + break; + } + } + } + int numberOfCameras = _getNumberOfCameras(); + if (exposeAuxCamera == false && (numberOfCameras > 2)) { + numberOfCameras = 2; + } + return numberOfCameras; + } + + /** + * Returns the number of physical cameras available on this device. + */ + /** @hide */ + public native static int _getNumberOfCameras(); /** * Returns the information about a particular camera. @@ -284,7 +341,14 @@ public class Camera { * low-level failure). */ public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) { - _getCameraInfo(cameraId, cameraInfo); + if(cameraId >= getNumberOfCameras()){ + throw new RuntimeException("Unknown camera ID"); + } + try { + _getCameraInfo(cameraId, cameraInfo); + } catch (RuntimeException e) { + Log.e(TAG, "Lock screen is disabled, facelock can't get camera info"); + } IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); IAudioService audioService = IAudioService.Stub.asInterface(b); try { @@ -317,6 +381,17 @@ public static class CameraInfo { */ public static final int CAMERA_FACING_FRONT = 1; + /* ### QC ADD-ONS: START TBD*/ + /** @hide + * camera is in ZSL mode. + */ + public static final int CAMERA_SUPPORT_MODE_ZSL = 2; + + /** @hide + * camera is in non-ZSL mode. + */ + public static final int CAMERA_SUPPORT_MODE_NONZSL = 3; + /* ### QC ADD-ONS: END */ /** * The direction that the camera faces. It should be * CAMERA_FACING_BACK or CAMERA_FACING_FRONT. @@ -502,6 +577,10 @@ private int cameraInitVersion(int cameraId, int halVersion) { mPostviewCallback = null; mUsingPreviewAllocation = false; mZoomListener = null; + /* ### QC ADD-ONS: START */ + mCameraDataCallback = null; + mCameraMetaDataCallback = null; + /* ### QC ADD-ONS: END */ Looper looper; if ((looper = Looper.myLooper()) != null) { @@ -512,8 +591,21 @@ private int cameraInitVersion(int cameraId, int halVersion) { mEventHandler = null; } - return native_setup(new WeakReference(this), cameraId, halVersion, - ActivityThread.currentOpPackageName()); + String packageName = ActivityThread.currentOpPackageName(); + + //Force HAL1 if the package name falls in this bucket + String packageList = SystemProperties.get("vendor.camera.hal1.packagelist", ""); + if (packageList.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageList); + for (String str : splitter) { + if (packageName.equals(str)) { + halVersion = CAMERA_HAL_API_VERSION_1_0; + break; + } + } + } + return native_setup(new WeakReference(this), cameraId, halVersion, packageName); } private int cameraInitNormal(int cameraId) { @@ -540,6 +632,9 @@ public int cameraInitUnspecified(int cameraId) { /** used by Camera#open, Camera#open(int) */ Camera(int cameraId) { + if(cameraId >= getNumberOfCameras()){ + throw new RuntimeException("Unknown camera ID"); + } int err = cameraInitNormal(cameraId); if (checkInitErrors(err)) { if (err == -EACCES) { @@ -862,6 +957,7 @@ public final void stopPreview() { * @see android.media.MediaActionSound */ public final void setPreviewCallback(PreviewCallback cb) { + android.util.SeempLog.record(66); mPreviewCallback = cb; mOneShot = false; mWithBuffer = false; @@ -890,6 +986,7 @@ public final void setPreviewCallback(PreviewCallback cb) { * @see android.media.MediaActionSound */ public final void setOneShotPreviewCallback(PreviewCallback cb) { + android.util.SeempLog.record(68); mPreviewCallback = cb; mOneShot = true; mWithBuffer = false; @@ -930,6 +1027,7 @@ public final void setOneShotPreviewCallback(PreviewCallback cb) { * @see android.media.MediaActionSound */ public final void setPreviewCallbackWithBuffer(PreviewCallback cb) { + android.util.SeempLog.record(67); mPreviewCallback = cb; mOneShot = false; mWithBuffer = true; @@ -1258,7 +1356,23 @@ public void handleMessage(Message msg) { mAutoFocusMoveCallback.onAutoFocusMoving(msg.arg1 == 0 ? false : true, mCamera); } return; + /* ### QC ADD-ONS: START */ + case CAMERA_MSG_STATS_DATA: + int statsdata[] = new int[257]; + for(int i =0; i<257; i++ ) { + statsdata[i] = byteToInt( (byte[])msg.obj, i*4); + } + if (mCameraDataCallback != null) { + mCameraDataCallback.onCameraData(statsdata, mCamera); + } + return; + case CAMERA_MSG_META_DATA: + if (mCameraMetaDataCallback != null) { + mCameraMetaDataCallback.onCameraMetaData((byte[])msg.obj, mCamera); + } + return; + /* ### QC ADD-ONS: END */ default: Log.e(TAG, "Unknown message type " + msg.what); return; @@ -1491,6 +1605,7 @@ public interface PictureCallback { */ public final void takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback jpeg) { + android.util.SeempLog.record(65); takePicture(shutter, raw, null, jpeg); } private native final void native_takePicture(int msgType); @@ -1529,6 +1644,7 @@ public final void takePicture(ShutterCallback shutter, PictureCallback raw, */ public final void takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback postview, PictureCallback jpeg) { + android.util.SeempLog.record(65); mShutterCallback = shutter; mRawImageCallback = raw; mPostviewCallback = postview; @@ -1776,6 +1892,20 @@ private void updateAppOpsPlayAudio() { } } + /** + * Send a vendor-specific camera command + * + * @hide + */ + public final void sendVendorCommand(int cmd, int arg1, int arg2) { + if (cmd < 1000) { + throw new IllegalArgumentException("Command numbers must be at least 1000"); + } + _sendVendorCommand(cmd, arg1, arg2); + } + + private native final void _sendVendorCommand(int cmd, int arg1, int arg2); + /** * Callback interface for zoom changes during a smooth zoom operation. * @@ -2120,6 +2250,27 @@ public Parameters getParameters() { return p; } + /** @hide + * Returns the current cct value of white balance. + * + * If it's in AWB mode, cct is determined by stats/awb module. + * + * If it's in Manual WB mode, it actually returns cct value + * set by user via {@link #setParameters(Camera.Parameters)}. + */ + public int getWBCurrentCCT() { + Parameters p = new Parameters(); + String s = native_getParameters(); + p.unflatten(s); + + int cct = 0; + if (p.getWBCurrentCCT() != null) { + cct = Integer.parseInt(p.getWBCurrentCCT()); + } + + return cct; + } + /** * Returns an empty {@link Parameters} for testing purpose. * @@ -2132,6 +2283,166 @@ public static Parameters getEmptyParameters() { return camera.new Parameters(); } + /* ### QC ADD-ONS: START */ + private static int byteToInt(byte[] b, int offset) { + int value = 0; + for (int i = 0; i < 4; i++) { + int shift = (4 - 1 - i) * 8; + value += (b[(3-i) + offset] & 0x000000FF) << shift; + } + return value; + } + /** @hide + * Handles the callback for when Camera Data is available. + * data is read from the camera. + */ + public interface CameraDataCallback { + /** + * Callback for when camera data is available. + * + * @param data a int array of the camera data + * @param camera the Camera service object + */ + void onCameraData(int[] data, Camera camera); + }; + + /** @hide + * Set camera histogram mode and registers a callback function to run. + * Only valid after startPreview() has been called. + * + * @param cb the callback to run + */ + public final void setHistogramMode(CameraDataCallback cb) + { + mCameraDataCallback = cb; + native_setHistogramMode(cb!=null); + } + private native final void native_setHistogramMode(boolean mode); + + /** @hide + * Set camera histogram command to send data. + * + */ + public final void sendHistogramData() + { + native_sendHistogramData(); + } + private native final void native_sendHistogramData(); + + /** @hide + * Handles the callback for when Camera Meta Data is available. + * Meta data is read from the camera. + */ + public interface CameraMetaDataCallback { + /** + * Callback for when camera meta data is available. + * + * @param data a byte array of the camera meta data + * @param camera the Camera service object + */ + void onCameraMetaData(byte[] data, Camera camera); + }; + + /** @hide + * Set camera meta data and registers a callback function to run. + * Only valid after startPreview() has been called. + * + * @param cb the callback to run + */ + public final void setMetadataCb(CameraMetaDataCallback cb) + { + mCameraMetaDataCallback = cb; + native_setMetadataCb(cb!=null); + } + private native final void native_setMetadataCb(boolean mode); + + /** @hide + * Set camera face detection command to send meta data. + */ + public final void sendMetaData() + { + native_sendMetaData(); + } + private native final void native_sendMetaData(); + + /** @hide + * Configure longshot mode. Available only in ZSL. + * + * @param enable enable/disable this mode + */ + public final void setLongshot(boolean enable) + { + native_setLongshot(enable); + } + private native final void native_setLongshot(boolean enable); + + /** @hide + * Stop longshot. Available only in ZSL. + */ + public final void stopLongshot() + { + native_stopLongshot(); + } + private native final void native_stopLongshot(); + + /** @hide + * Handles the Touch Co-ordinate. + */ + public class Coordinate { + /** + * Sets the x,y co-ordinates for a touch event + * + * @param x the x co-ordinate (pixels) + * @param y the y co-ordinate (pixels) + */ + public Coordinate(int x, int y) { + xCoordinate = x; + yCoordinate = y; + } + /** + * Compares {@code obj} to this co-ordinate. + * + * @param obj the object to compare this co-ordinate with. + * @return {@code true} if the xCoordinate and yCoordinate of {@code obj} is the + * same as those of this coordinate. {@code false} otherwise. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Coordinate)) { + return false; + } + Coordinate c = (Coordinate) obj; + return xCoordinate == c.xCoordinate && yCoordinate == c.yCoordinate; + } + + /** x co-ordinate for the touch event*/ + public int xCoordinate; + + /** y co-ordinate for the touch event */ + public int yCoordinate; + }; + + /** @hide + * Returns the current focus position. + * + * If it's in AF mode, it's the lens position after af is done. + * + * If it's in Manual Focus mode, it actually returns the value + * set by user via {@link #setParameters(Camera.Parameters)}. + */ + public int getCurrentFocusPosition() { + Parameters p = new Parameters(); + String s = native_getParameters(); + p.unflatten(s); + + int focus_pos = -1; + if (p.getCurrentFocusPosition() != null) { + focus_pos = Integer.parseInt(p.getCurrentFocusPosition()); + } + return focus_pos; + } + + /* ### QC ADD-ONS: END */ /** * Returns a copied {@link Parameters}; for shim use only. * @@ -2379,6 +2690,10 @@ public class Parameters { public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight"; public static final String WHITE_BALANCE_TWILIGHT = "twilight"; public static final String WHITE_BALANCE_SHADE = "shade"; + /** @hide + * wb manual cct mode. + */ + public static final String WHITE_BALANCE_MANUAL_CCT = "manual-cct"; // Values for color effect settings. public static final String EFFECT_NONE = "none"; @@ -2426,6 +2741,11 @@ public class Parameters { */ public static final String FLASH_MODE_TORCH = "torch"; + /** @hide + * Scene mode is off. + */ + public static final String SCENE_MODE_ASD = "asd"; + /** * Scene mode is off. */ @@ -2502,6 +2822,14 @@ public class Parameters { * Capture the naturally warm color of scenes lit by candles. */ public static final String SCENE_MODE_CANDLELIGHT = "candlelight"; + /** @hide + * SCENE_MODE_BACKLIGHT + **/ + public static final String SCENE_MODE_BACKLIGHT = "backlight"; + /** @hide + * SCENE_MODE_FLOWERS + **/ + public static final String SCENE_MODE_FLOWERS = "flowers"; /** * Applications are looking for a barcode. Camera driver will be @@ -2544,6 +2872,13 @@ public class Parameters { */ public static final String FOCUS_MODE_FIXED = "fixed"; + /** @hide + * Normal focus mode. Applications should call + * {@link #autoFocus(AutoFocusCallback)} to start the focus in this + * mode. + */ + public static final String FOCUS_MODE_NORMAL = "normal"; + /** * Extended depth of field (EDOF). Focusing is done digitally and * continuously. Applications should not call {@link @@ -2596,6 +2931,11 @@ public class Parameters { */ public static final String FOCUS_MODE_CONTINUOUS_PICTURE = "continuous-picture"; + /** @hide + * manual focus mode + */ + public static final String FOCUS_MODE_MANUAL_POSITION = "manual"; + // Indices for focus distance array. /** * The array index of near focus distance for use with @@ -2632,11 +2972,15 @@ public class Parameters { // Formats for setPreviewFormat and setPictureFormat. private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp"; private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp"; + private static final String PIXEL_FORMAT_YUV420SP_ADRENO = "yuv420sp-adreno"; private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv"; private static final String PIXEL_FORMAT_YUV420P = "yuv420p"; private static final String PIXEL_FORMAT_RGB565 = "rgb565"; private static final String PIXEL_FORMAT_JPEG = "jpeg"; private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb"; + private static final String PIXEL_FORMAT_RAW = "raw"; + private static final String PIXEL_FORMAT_YV12 = "yv12"; + private static final String PIXEL_FORMAT_NV12 = "nv12"; /** * Order matters: Keys that are {@link #set(String, String) set} later @@ -3454,8 +3798,11 @@ public void setGpsProcessingMethod(String processing_method) { * parameters. */ public void removeGpsData() { + remove(KEY_QC_GPS_LATITUDE_REF); remove(KEY_GPS_LATITUDE); + remove(KEY_QC_GPS_LONGITUDE_REF); remove(KEY_GPS_LONGITUDE); + remove(KEY_QC_GPS_ALTITUDE_REF); remove(KEY_GPS_ALTITUDE); remove(KEY_GPS_TIMESTAMP); remove(KEY_GPS_PROCESSING_METHOD); @@ -4346,6 +4693,7 @@ private void splitInt(String str, int[] output) { splitter.setString(str); int index = 0; for (String s : splitter) { + s = s.replaceAll("\\s",""); output[index++] = Integer.parseInt(s); } } @@ -4478,5 +4826,1231 @@ private boolean same(String s1, String s2) { if (s1 != null && s1.equals(s2)) return true; return false; } + /* ### QC ADD-ONS: START */ + + /* ### QC ADDED PARAMETER KEYS*/ + private static final String KEY_QC_HFR_SIZE = "hfr-size"; + private static final String KEY_QC_PREVIEW_FRAME_RATE_MODE = "preview-frame-rate-mode"; + private static final String KEY_QC_PREVIEW_FRAME_RATE_AUTO_MODE = "frame-rate-auto"; + private static final String KEY_QC_PREVIEW_FRAME_RATE_FIXED_MODE = "frame-rate-fixed"; + private static final String KEY_QC_GPS_LATITUDE_REF = "gps-latitude-ref"; + private static final String KEY_QC_GPS_LONGITUDE_REF = "gps-longitude-ref"; + private static final String KEY_QC_GPS_ALTITUDE_REF = "gps-altitude-ref"; + private static final String KEY_QC_GPS_STATUS = "gps-status"; + private static final String KEY_QC_EXIF_DATETIME = "exif-datetime"; + private static final String KEY_QC_TOUCH_AF_AEC = "touch-af-aec"; + private static final String KEY_QC_TOUCH_INDEX_AEC = "touch-index-aec"; + private static final String KEY_QC_TOUCH_INDEX_AF = "touch-index-af"; + private static final String KEY_QC_MANUAL_FOCUS_POSITION = "manual-focus-position"; + private static final String KEY_QC_MANUAL_FOCUS_POS_TYPE = "manual-focus-pos-type"; + private static final String KEY_QC_SCENE_DETECT = "scene-detect"; + private static final String KEY_QC_ISO_MODE = "iso"; + private static final String KEY_QC_EXPOSURE_TIME = "exposure-time"; + private static final String KEY_QC_MIN_EXPOSURE_TIME = "min-exposure-time"; + private static final String KEY_QC_MAX_EXPOSURE_TIME = "max-exposure-time"; + private static final String KEY_QC_LENSSHADE = "lensshade"; + private static final String KEY_QC_HISTOGRAM = "histogram"; + private static final String KEY_QC_SKIN_TONE_ENHANCEMENT = "skinToneEnhancement"; + private static final String KEY_QC_AUTO_EXPOSURE = "auto-exposure"; + private static final String KEY_QC_SHARPNESS = "sharpness"; + private static final String KEY_QC_MAX_SHARPNESS = "max-sharpness"; + private static final String KEY_QC_CONTRAST = "contrast"; + private static final String KEY_QC_MAX_CONTRAST = "max-contrast"; + private static final String KEY_QC_SATURATION = "saturation"; + private static final String KEY_QC_MAX_SATURATION = "max-saturation"; + private static final String KEY_QC_DENOISE = "denoise"; + private static final String KEY_QC_CONTINUOUS_AF = "continuous-af"; + private static final String KEY_QC_SELECTABLE_ZONE_AF = "selectable-zone-af"; + private static final String KEY_QC_FACE_DETECTION = "face-detection"; + private static final String KEY_QC_MEMORY_COLOR_ENHANCEMENT = "mce"; + private static final String KEY_QC_REDEYE_REDUCTION = "redeye-reduction"; + private static final String KEY_QC_ZSL = "zsl"; + private static final String KEY_QC_CAMERA_MODE = "camera-mode"; + private static final String KEY_QC_VIDEO_HIGH_FRAME_RATE = "video-hfr"; + private static final String KEY_QC_VIDEO_HDR = "video-hdr"; + private static final String KEY_QC_POWER_MODE = "power-mode"; + private static final String KEY_QC_POWER_MODE_SUPPORTED = "power-mode-supported"; + private static final String KEY_QC_WB_MANUAL_CCT = "wb-manual-cct"; + private static final String KEY_QC_MIN_WB_CCT = "min-wb-cct"; + private static final String KEY_QC_MAX_WB_CCT = "max-wb-cct"; + private static final String KEY_QC_AUTO_HDR_ENABLE = "auto-hdr-enable"; + private static final String KEY_QC_VIDEO_ROTATION = "video-rotation"; + + /** @hide + * KEY_QC_AE_BRACKET_HDR + **/ + public static final String KEY_QC_AE_BRACKET_HDR = "ae-bracket-hdr"; + + /* ### QC ADDED PARAMETER VALUES*/ + + // Values for touch af/aec settings. + /** @hide + * TOUCH_AF_AEC_OFF + **/ + public static final String TOUCH_AF_AEC_OFF = "touch-off"; + /** @hide + * TOUCH_AF_AEC_ON + **/ + public static final String TOUCH_AF_AEC_ON = "touch-on"; + + // Values for auto exposure settings. + /** @hide + * Auto exposure frame-avg + **/ + public static final String AUTO_EXPOSURE_FRAME_AVG = "frame-average"; + /** @hide + * Auto exposure center weighted + **/ + public static final String AUTO_EXPOSURE_CENTER_WEIGHTED = "center-weighted"; + /** @hide + * Auto exposure spot metering + **/ + public static final String AUTO_EXPOSURE_SPOT_METERING = "spot-metering"; + + //Values for ISO settings + /** @hide + * ISO_AUTO + **/ + public static final String ISO_AUTO = "auto"; + /** @hide + * ISO_HJR + **/ + public static final String ISO_HJR = "ISO_HJR"; + /** @hide + * ISO_100 + **/ + public static final String ISO_100 = "ISO100"; + /** @hide + * ISO_200 + **/ + public static final String ISO_200 = "ISO200"; + /** @hide + * ISO_400 + **/ + public static final String ISO_400 = "ISO400"; + /** @hide + * ISO_800 + **/ + public static final String ISO_800 = "ISO800"; + /** @hide + * ISO_1600 + **/ + public static final String ISO_1600 = "ISO1600"; + + /** @hide + * ISO_3200 + **/ + public static final String ISO_3200 = "ISO3200"; + + //Values for Lens Shading + /** @hide + * LENSSHADE_ENABLE + **/ + public static final String LENSSHADE_ENABLE = "enable"; + /** @hide + * LENSSHADE_DISABLE + **/ + public static final String LENSSHADE_DISABLE= "disable"; + + //Values for Histogram + /** @hide + * Histogram enable + **/ + public static final String HISTOGRAM_ENABLE = "enable"; + /** @hide + * Histogram disable + **/ + public static final String HISTOGRAM_DISABLE= "disable"; + + //Values for Skin Tone Enhancement + /** @hide + * SKIN_TONE_ENHANCEMENT_ENABLE + **/ + public static final String SKIN_TONE_ENHANCEMENT_ENABLE = "enable"; + /** @hide + * SKIN_TONE_ENHANCEMENT_DISABLE + **/ + public static final String SKIN_TONE_ENHANCEMENT_DISABLE= "disable"; + + // Values for MCE settings. + /** @hide + * MCE_ENaBLE + **/ + public static final String MCE_ENABLE = "enable"; + /** @hide + * MCE_DISABLE + **/ + public static final String MCE_DISABLE = "disable"; + + // Values for ZSL settings. + /** @hide + * ZSL_ON + **/ + public static final String ZSL_ON = "on"; + /** @hide + * ZSL_OFF + **/ + public static final String ZSL_OFF = "off"; + + // Values for HDR Bracketing settings. + + /** @hide + * AEC bracketing off + **/ + public static final String AE_BRACKET_HDR_OFF = "Off"; + /** @hide + * AEC bracketing hdr + **/ + public static final String AE_BRACKET_HDR = "HDR"; + /** @hide + * AEC bracketing aec-bracket + **/ + public static final String AE_BRACKET = "AE-Bracket"; + + // Values for Power mode. + /** @hide + * LOW_POWER + **/ + public static final String LOW_POWER = "Low_Power"; + /** @hide + * NORMAL_POWER + **/ + public static final String NORMAL_POWER = "Normal_Power"; + + // Values for HFR settings. + /** @hide + * VIDEO_HFR_OFF + **/ + public static final String VIDEO_HFR_OFF = "off"; + /** @hide + * VIDEO_HFR_2X + **/ + public static final String VIDEO_HFR_2X = "60"; + /** @hide + * VIDEO_HFR_3X + **/ + public static final String VIDEO_HFR_3X = "90"; + /** @hide + * VIDEO_HFR_4X + **/ + public static final String VIDEO_HFR_4X = "120"; + + // Values for auto scene detection settings. + /** @hide + * SCENE_DETECT_OFF + **/ + public static final String SCENE_DETECT_OFF = "off"; + /** @hide + * SCENE_DETECT_ON + **/ + public static final String SCENE_DETECT_ON = "on"; + + //Values for Continuous AF + + /** @hide + * CAF off + **/ + public static final String CONTINUOUS_AF_OFF = "caf-off"; + /** @hide + * CAF on + **/ + public static final String CONTINUOUS_AF_ON = "caf-on"; + /** @hide + * Denoise off + **/ + public static final String DENOISE_OFF = "denoise-off"; + /** @hide + * Denoise on + **/ + public static final String DENOISE_ON = "denoise-on"; + + // Values for Redeye Reduction settings. + /** @hide + * REDEYE_REDUCTION_ENABLE + **/ + public static final String REDEYE_REDUCTION_ENABLE = "enable"; + /** @hide + * REDEYE_REDUCTION_DISABLE + **/ + public static final String REDEYE_REDUCTION_DISABLE = "disable"; + + // Values for selectable zone af settings. + /** @hide + * SELECTABLE_ZONE_AF_AUTO + **/ + public static final String SELECTABLE_ZONE_AF_AUTO = "auto"; + /** @hide + * SELECTABLE_ZONE_AF_SPOTMETERING + **/ + public static final String SELECTABLE_ZONE_AF_SPOTMETERING = "spot-metering"; + /** @hide + * SELECTABLE_ZONE_AF_CENTER_WEIGHTED + **/ + public static final String SELECTABLE_ZONE_AF_CENTER_WEIGHTED = "center-weighted"; + /** @hide + * SELECTABLE_ZONE_AF_FRAME_AVERAGE + **/ + public static final String SELECTABLE_ZONE_AF_FRAME_AVERAGE = "frame-average"; + + // Values for Face Detection settings. + /** @hide + * Face Detection off + **/ + public static final String FACE_DETECTION_OFF = "off"; + /** @hide + * Face Detction on + **/ + public static final String FACE_DETECTION_ON = "on"; + + // Values for video rotation settings. + + /** @hide + * VIDEO_ROTATION_0 + **/ + public static final String VIDEO_ROTATION_0 = "0"; + /** @hide + * VIDEO_ROTATION_90 + **/ + public static final String VIDEO_ROTATION_90 = "90"; + /** @hide + * VIDEO_ROTATION_180 + **/ + public static final String VIDEO_ROTATION_180 = "180"; + /** @hide + * VIDEO_ROTATION_270 + **/ + public static final String VIDEO_ROTATION_270 = "270"; + + /* ### QC ADDED PARAMETER APIS*/ + /** @hide + * Gets the supported preview sizes in high frame rate recording mode. + * + * @return a list of Size object. This method will always return a list + * with at least one element. + */ + public List getSupportedHfrSizes() { + String str = get(KEY_QC_HFR_SIZE + SUPPORTED_VALUES_SUFFIX); + return splitSize(str); + } + + /** @hide + * Gets the supported Touch AF/AEC setting. + * + * @return a List of TOUCH_AF_AEC_XXX string constants. null if TOUCH AF/AEC + * setting is not supported. + * + */ + public List getSupportedTouchAfAec() { + String str = get(KEY_QC_TOUCH_AF_AEC + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** + * Gets the supported Touch AF/AEC setting. + * + * @return a List of TOUCH_AF_AEC_XXX string constants. null if TOUCH AF/AEC + * setting is not supported. + * + */ + + /** @hide + * Gets the supported frame rate modes. + * + * @return a List of FRAME_RATE_XXX_MODE string constant. null if this + * setting is not supported. + */ + public List getSupportedPreviewFrameRateModes() { + String str = get(KEY_QC_PREVIEW_FRAME_RATE_MODE + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported auto scene detection modes. + * + * @return a List of SCENE_DETECT_XXX string constant. null if scene detection + * setting is not supported. + * + */ + public List getSupportedSceneDetectModes() { + String str = get(KEY_QC_SCENE_DETECT + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported ISO values. + * + * @return a List of FLASH_MODE_XXX string constants. null if flash mode + * setting is not supported. + */ + public List getSupportedIsoValues() { + String str = get(KEY_QC_ISO_MODE + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported Lensshade modes. + * + * @return a List of LENS_MODE_XXX string constants. null if lens mode + * setting is not supported. + */ + public List getSupportedLensShadeModes() { + String str = get(KEY_QC_LENSSHADE + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported Histogram modes. + * + * @return a List of HISTOGRAM_XXX string constants. null if histogram mode + * setting is not supported. + */ + public List getSupportedHistogramModes() { + String str = get(KEY_QC_HISTOGRAM + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported Skin Tone Enhancement modes. + * + * @return a List of SKIN_TONE_ENHANCEMENT_XXX string constants. null if skin tone enhancement + * setting is not supported. + */ + public List getSupportedSkinToneEnhancementModes() { + String str = get(KEY_QC_SKIN_TONE_ENHANCEMENT + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported auto exposure setting. + * + * @return a List of AUTO_EXPOSURE_XXX string constants. null if auto exposure + * setting is not supported. + */ + public List getSupportedAutoexposure() { + String str = get(KEY_QC_AUTO_EXPOSURE + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported MCE modes. + * + * @return a List of MCE_ENABLE/DISABLE string constants. null if MCE mode + * setting is not supported. + */ + public List getSupportedMemColorEnhanceModes() { + String str = get(KEY_QC_MEMORY_COLOR_ENHANCEMENT + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported ZSL modes. + * + * @return a List of ZSL_OFF/OFF string constants. null if ZSL mode + * setting is not supported. + */ + public List getSupportedZSLModes() { + String str = get(KEY_QC_ZSL + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported Video HDR modes. + * + * @return a List of Video HDR_OFF/OFF string constants. null if + * Video HDR mode setting is not supported. + */ + public List getSupportedVideoHDRModes() { + String str = get(KEY_QC_VIDEO_HDR + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported HFR modes. + * + * @return a List of VIDEO_HFR_XXX string constants. null if hfr mode + * setting is not supported. + */ + public List getSupportedVideoHighFrameRateModes() { + String str = get(KEY_QC_VIDEO_HIGH_FRAME_RATE + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported Continuous AF modes. + * + * @return a List of CONTINUOUS_AF_XXX string constant. null if continuous AF + * setting is not supported. + * + */ + public List getSupportedContinuousAfModes() { + String str = get(KEY_QC_CONTINUOUS_AF + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported DENOISE modes. + * + * @return a List of DENOISE_XXX string constant. null if DENOISE + * setting is not supported. + * + */ + public List getSupportedDenoiseModes() { + String str = get(KEY_QC_DENOISE + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported selectable zone af setting. + * + * @return a List of SELECTABLE_ZONE_AF_XXX string constants. null if selectable zone af + * setting is not supported. + */ + public List getSupportedSelectableZoneAf() { + String str = get(KEY_QC_SELECTABLE_ZONE_AF + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported face detection modes. + * + * @return a List of FACE_DETECTION_XXX string constant. null if face detection + * setting is not supported. + * + */ + public List getSupportedFaceDetectionModes() { + String str = get(KEY_QC_FACE_DETECTION + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Gets the supported redeye reduction modes. + * + * @return a List of REDEYE_REDUCTION_XXX string constant. null if redeye reduction + * setting is not supported. + * + */ + public List getSupportedRedeyeReductionModes() { + String str = get(KEY_QC_REDEYE_REDUCTION + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + /** @hide + * Sets GPS altitude reference. This will be stored in JPEG EXIF header. + * @param altRef reference GPS altitude in meters. + */ + public void setGpsAltitudeRef(double altRef) { + set(KEY_QC_GPS_ALTITUDE_REF, Double.toString(altRef)); + } + + /** @hide + * Sets GPS Status. This will be stored in JPEG EXIF header. + * + * @param status GPS status (UTC in seconds since January 1, + * 1970). + */ + public void setGpsStatus(double status) { + set(KEY_QC_GPS_STATUS, Double.toString(status)); + } + + /** @hide + * Sets the touch co-ordinate for Touch AEC. + * + * @param x the x co-ordinate of the touch event + * @param y the y co-ordinate of the touch event + * + */ + public void setTouchIndexAec(int x, int y) { + String v = Integer.toString(x) + "x" + Integer.toString(y); + set(KEY_QC_TOUCH_INDEX_AEC, v); + } + + /** @hide + * Returns the touch co-ordinates of the touch event. + * + * @return a Index object with the x and y co-ordinated + * for the touch event + * + */ + public Coordinate getTouchIndexAec() { + String pair = get(KEY_QC_TOUCH_INDEX_AEC); + return strToCoordinate(pair); + } + + /** @hide + * Sets the touch co-ordinate for Touch AF. + * + * @param x the x co-ordinate of the touch event + * @param y the y co-ordinate of the touch event + * + */ + public void setTouchIndexAf(int x, int y) { + String v = Integer.toString(x) + "x" + Integer.toString(y); + set(KEY_QC_TOUCH_INDEX_AF, v); + } + + /** @hide + * Returns the touch co-ordinates of the touch event. + * + * @return a Index object with the x and y co-ordinated + * for the touch event + * + */ + public Coordinate getTouchIndexAf() { + String pair = get(KEY_QC_TOUCH_INDEX_AF); + return strToCoordinate(pair); + } + /** @hide + * Set Sharpness Level + * + * @param sharpness level + */ + public void setSharpness(int sharpness){ + if((sharpness < 0) || (sharpness > getMaxSharpness()) ) + throw new IllegalArgumentException( + "Invalid Sharpness " + sharpness); + + set(KEY_QC_SHARPNESS, String.valueOf(sharpness)); + } + + /** @hide + * Set Contrast Level + * + * @param contrast level + */ + public void setContrast(int contrast){ + if((contrast < 0 ) || (contrast > getMaxContrast())) + throw new IllegalArgumentException( + "Invalid Contrast " + contrast); + + set(KEY_QC_CONTRAST, String.valueOf(contrast)); + } + + /** @hide + * Set Saturation Level + * + * @param saturation level + */ + public void setSaturation(int saturation){ + if((saturation < 0 ) || (saturation > getMaxSaturation())) + throw new IllegalArgumentException( + "Invalid Saturation " + saturation); + + set(KEY_QC_SATURATION, String.valueOf(saturation)); + } + + /** @hide + * @return true if full size video snapshot is supported. + */ + public boolean isPowerModeSupported() { + String str = get(KEY_QC_POWER_MODE_SUPPORTED); + return TRUE.equals(str); + } + + /** @hide + * Get Sharpness level + * + * @return sharpness level + */ + public int getSharpness(){ + return getInt(KEY_QC_SHARPNESS); + } + + /** @hide + * Get Max Sharpness Level + * + * @return max sharpness level + */ + public int getMaxSharpness(){ + return getInt(KEY_QC_MAX_SHARPNESS); + } + + /** @hide + * Get Contrast level + * + * @return contrast level + */ + public int getContrast(){ + return getInt(KEY_QC_CONTRAST); + } + + /** @hide + * Get Max Contrast Level + * + * @return max contrast level + */ + public int getMaxContrast(){ + return getInt(KEY_QC_MAX_CONTRAST); + } + + /** @hide + * Get Saturation level + * + * @return saturation level + */ + public int getSaturation(){ + return getInt(KEY_QC_SATURATION); + } + + /** @hide + * Get Max Saturation Level + * + * @return max contrast level + */ + public int getMaxSaturation(){ + return getInt(KEY_QC_MAX_SATURATION); + } + + /** @hide + * Sets GPS latitude reference coordinate. This will be stored in JPEG EXIF + * header. + * @param latRef GPS latitude reference coordinate. + */ + public void setGpsLatitudeRef(String latRef) { + set(KEY_QC_GPS_LATITUDE_REF, latRef); + } + + /** @hide + * Sets GPS longitude reference coordinate. This will be stored in JPEG EXIF + * header. + * @param lonRef GPS longitude reference coordinate. + */ + public void setGpsLongitudeRef(String lonRef) { + set(KEY_QC_GPS_LONGITUDE_REF, lonRef); + } + + /** @hide + * Sets system timestamp. This will be stored in JPEG EXIF header. + * + * @param dateTime current timestamp (UTC in seconds since January 1, + * 1970). + */ + public void setExifDateTime(String dateTime) { + set(KEY_QC_EXIF_DATETIME, dateTime); + } + + /** @hide + * Gets the current Touch AF/AEC setting. + * + * @return one of TOUCH_AF_AEC_XXX string constant. null if Touch AF/AEC + * setting is not supported. + * + */ + public String getTouchAfAec() { + return get(KEY_QC_TOUCH_AF_AEC); + } + + /** @hide + * Sets the current TOUCH AF/AEC setting. + * + * @param value TOUCH_AF_AEC_XXX string constants. + * + */ + public void setTouchAfAec(String value) { + set(KEY_QC_TOUCH_AF_AEC, value); + } + + /** @hide + * Gets the current redeye reduction setting. + * + * @return one of REDEYE_REDUCTION_XXX string constant. null if redeye reduction + * setting is not supported. + * + */ + public String getRedeyeReductionMode() { + return get(KEY_QC_REDEYE_REDUCTION); + } + + /** @hide + * Sets the redeye reduction. Other parameters may be changed after changing + * redeye reduction. After setting redeye reduction, + * applications should call getParameters to know if some parameters are + * changed. + * + * @param value REDEYE_REDUCTION_XXX string constants. + * + */ + public void setRedeyeReductionMode(String value) { + set(KEY_QC_REDEYE_REDUCTION, value); + } + + /** @hide + * Gets the frame rate mode setting. + * + * @return one of FRAME_RATE_XXX_MODE string constant. null if this + * setting is not supported. + */ + public String getPreviewFrameRateMode() { + return get(KEY_QC_PREVIEW_FRAME_RATE_MODE); + } + + /** @hide + * Sets the frame rate mode. + * + * @param value FRAME_RATE_XXX_MODE string constants. + */ + public void setPreviewFrameRateMode(String value) { + set(KEY_QC_PREVIEW_FRAME_RATE_MODE, value); + } + + /** @hide + * Gets the current auto scene detection setting. + * + * @return one of SCENE_DETECT_XXX string constant. null if auto scene detection + * setting is not supported. + * + */ + public String getSceneDetectMode() { + return get(KEY_QC_SCENE_DETECT); + } + + /** @hide + * Sets the auto scene detect. Other parameters may be changed after changing + * scene detect. After setting auto scene detection, + * applications should call getParameters to know if some parameters are + * changed. + * + * @param value SCENE_DETECT_XXX string constants. + * + */ + public void setSceneDetectMode(String value) { + set(KEY_QC_SCENE_DETECT, value); + } + + /** @hide + * Gets the current hdr bracketing mode setting. + * + * @return current hdr bracketing mode. + * @see #KEY_AE_BRACKET_OFF + * @see #KEY_AE_BRACKET_HDR + * @see #KEY_AE_BRACKET_BRACKATING + */ + public String getAEBracket() { + return get(KEY_QC_AE_BRACKET_HDR); + } + + /** @hide + * Sets the Power mode. + * + * @param value Power mode. + * @see #getPowerMode() + */ + public void setPowerMode(String value) { + set(KEY_QC_POWER_MODE, value); + } + + /** @hide + * Gets the current power mode setting. + * + * @return current power mode. null if power mode setting is not + * supported. + * @see #POWER_MODE_LOW + * @see #POWER_MODE_NORMAL + */ + public String getPowerMode() { + return get(KEY_QC_POWER_MODE); + } + + /** @hide + * Set HDR-Bracketing Level + * + * @param value HDR-Bracketing + */ + public void setAEBracket(String value){ + set(KEY_QC_AE_BRACKET_HDR, value); + } + + /** @hide + * Gets the current ISO setting. + * + * @return one of ISO_XXX string constant. null if ISO + * setting is not supported. + */ + public String getISOValue() { + return get(KEY_QC_ISO_MODE); + } + + /** @hide + * Sets the ISO. + * + * @param iso ISO_XXX string constant. + */ + public void setISOValue(String iso) { + set(KEY_QC_ISO_MODE, iso); + } + + /** @hide + * Sets the exposure time. + * + * @param value exposure time. + */ + public void setExposureTime(int value) { + set(KEY_QC_EXPOSURE_TIME, Integer.toString(value)); + } + + /** @hide + * Gets the current exposure time. + * + * @return exposure time. + */ + public String getExposureTime() { + return get(KEY_QC_EXPOSURE_TIME); + } + + /** @hide + * Gets the min supported exposure time. + * + * @return min supported exposure time. + */ + public String getMinExposureTime() { + return get(KEY_QC_MIN_EXPOSURE_TIME); + } + + /** @hide + * Gets the max supported exposure time. + * + * @return max supported exposure time. + */ + public String getMaxExposureTime() { + return get(KEY_QC_MAX_EXPOSURE_TIME); + } + + /** @hide + * Gets the current LensShade Mode. + * + * @return LensShade Mode + */ + public String getLensShade() { + return get(KEY_QC_LENSSHADE); + } + + /** @hide + * Sets the current LensShade Mode. + * + * @return LensShade Mode + */ + public void setLensShade(String lensshade) { + set(KEY_QC_LENSSHADE, lensshade); + } + + /** @hide + * Gets the current auto exposure setting. + * + * @return one of AUTO_EXPOSURE_XXX string constant. null if auto exposure + * setting is not supported. + */ + public String getAutoExposure() { + return get(KEY_QC_AUTO_EXPOSURE); + } + + /** @hide + * Sets the current auto exposure setting. + * + * @param value AUTO_EXPOSURE_XXX string constants. + */ + public void setAutoExposure(String value) { + set(KEY_QC_AUTO_EXPOSURE, value); + } + + /** @hide + * Gets the current MCE Mode. + * + * @return MCE value + */ + public String getMemColorEnhance() { + return get(KEY_QC_MEMORY_COLOR_ENHANCEMENT); + } + + /** @hide + * Sets the current MCE Mode. + * + * @return MCE Mode + */ + public void setMemColorEnhance(String mce) { + set(KEY_QC_MEMORY_COLOR_ENHANCEMENT, mce); + } + + /** @hide + * Set white balance manual cct value. + * + * @param cct user CCT setting. + */ + public void setWBManualCCT(int cct) { + set(KEY_QC_WB_MANUAL_CCT, Integer.toString(cct)); + } + + /** @hide + * Gets the WB min supported CCT. + * + * @return min cct value. + */ + public String getWBMinCCT() { + return get(KEY_QC_MIN_WB_CCT); + } + + /** @hide + * Gets the WB max supported CCT. + * + * @return max cct value. + */ + public String getMaxWBCCT() { + return get(KEY_QC_MAX_WB_CCT); + } + + /** @hide + * Gets the current WB CCT. + * + * @return CCT value + */ + public String getWBCurrentCCT() { + return get(KEY_QC_WB_MANUAL_CCT); + } + + /** @hide + * Gets the current ZSL Mode. + * + * @return ZSL mode value + */ + public String getZSLMode() { + return get(KEY_QC_ZSL); + } + + /** @hide + * Sets the current ZSL Mode. ZSL mode is set as a 0th bit in KEY_CAMERA_MODE. + * + * @return null + */ + public void setZSLMode(String zsl) { + set(KEY_QC_ZSL, zsl); + } + + /** @hide + * Sets the current Auto HDR Mode. + * @ auto_hdr auto hdr string for enable/disable + * @return null + */ + public void setAutoHDRMode(String auto_hdr){ + set(KEY_QC_AUTO_HDR_ENABLE,auto_hdr); + } + + /** @hide + * Gets the current Camera Mode Flag. Camera mode includes a + * flag(byte) which indicates different camera modes. + * For now support for ZSL added at bit0 + * + * @return Camera Mode. + */ + public String getCameraMode() { + return get(KEY_QC_CAMERA_MODE); + } + + /** @hide + * Sets the current Camera Mode. + * + * @return null + */ + public void setCameraMode(int cameraMode) { + set(KEY_QC_CAMERA_MODE, cameraMode); + } + + private static final int MANUAL_FOCUS_POS_TYPE_INDEX = 0; + private static final int MANUAL_FOCUS_POS_TYPE_DAC = 1; + /** @hide + * Set focus position. + * + * @param pos user setting of focus position. + */ + public void setFocusPosition(int type, int pos) { + set(KEY_QC_MANUAL_FOCUS_POS_TYPE, Integer.toString(type)); + set(KEY_QC_MANUAL_FOCUS_POSITION, Integer.toString(pos)); + } + + /** @hide + * Gets the current focus position. + * + * @return current focus position + */ + public String getCurrentFocusPosition() { + return get(KEY_QC_MANUAL_FOCUS_POSITION); + } + + + /** @hide + * Gets the current HFR Mode. + * + * @return VIDEO_HFR_XXX string constants + */ + public String getVideoHighFrameRate() { + return get(KEY_QC_VIDEO_HIGH_FRAME_RATE); + } + + /** @hide + * Sets the current HFR Mode. + * + * @param hfr VIDEO_HFR_XXX string constants + */ + public void setVideoHighFrameRate(String hfr) { + set(KEY_QC_VIDEO_HIGH_FRAME_RATE, hfr); + } + + /** @hide + * Gets the current Video HDR Mode. + * + * @return Video HDR mode value + */ + public String getVideoHDRMode() { + return get(KEY_QC_VIDEO_HDR); + } + + /** @hide + * Sets the current Video HDR Mode. + * + * @return null + */ + public void setVideoHDRMode(String videohdr) { + set(KEY_QC_VIDEO_HDR, videohdr); + } + + /** @hide + * Gets the current DENOISE setting. + * + * @return one of DENOISE_XXX string constant. null if Denoise + * setting is not supported. + * + */ + public String getDenoise() { + return get(KEY_QC_DENOISE); + } + + /** @hide + * Gets the current Continuous AF setting. + * + * @return one of CONTINUOUS_AF_XXX string constant. null if continuous AF + * setting is not supported. + * + */ + public String getContinuousAf() { + return get(KEY_QC_CONTINUOUS_AF); + } + + /** @hide + * Sets the current Denoise mode. + * @param value DENOISE_XXX string constants. + * + */ + + public void setDenoise(String value) { + set(KEY_QC_DENOISE, value); + } + + /** @hide + * Sets the current Continuous AF mode. + * @param value CONTINUOUS_AF_XXX string constants. + * + */ + public void setContinuousAf(String value) { + set(KEY_QC_CONTINUOUS_AF, value); + } + + /** @hide + * Gets the current selectable zone af setting. + * + * @return one of SELECTABLE_ZONE_AF_XXX string constant. null if selectable zone af + * setting is not supported. + */ + public String getSelectableZoneAf() { + return get(KEY_QC_SELECTABLE_ZONE_AF); + } + + /** @hide + * Sets the current selectable zone af setting. + * + * @param value SELECTABLE_ZONE_AF_XXX string constants. + */ + public void setSelectableZoneAf(String value) { + set(KEY_QC_SELECTABLE_ZONE_AF, value); + } + + /** @hide + * Gets the current face detection setting. + * + * @return one of FACE_DETECTION_XXX string constant. null if face detection + * setting is not supported. + * + */ + public String getFaceDetectionMode() { + return get(KEY_QC_FACE_DETECTION); + } + + /** @hide + * Sets the auto scene detect. Other settings like Touch AF/AEC might be + * changed after setting face detection. + * + * @param value FACE_DETECTION_XXX string constants. + * + */ + public void setFaceDetectionMode(String value) { + set(KEY_QC_FACE_DETECTION, value); + } + + /** @hide + * Gets the current video rotation setting. + * + * @return one of VIDEO_QC_ROTATION_XXX string constant. null if video rotation + * setting is not supported. + */ + public String getVideoRotation() { + return get(KEY_QC_VIDEO_ROTATION); + } + + /** @hide + * Sets the current video rotation setting. + * + * @param value VIDEO_QC_ROTATION_XXX string constants. + */ + public void setVideoRotation(String value) { + set(KEY_QC_VIDEO_ROTATION, value); + } + /** @hide + * Gets the supported video rotation modes. + * + * @return a List of VIDEO_QC_ROTATION_XXX string constant. null if this + * setting is not supported. + */ + public List getSupportedVideoRotationValues() { + String str = get(KEY_QC_VIDEO_ROTATION + SUPPORTED_VALUES_SUFFIX); + return split(str); + } + + // Splits a comma delimited string to an ArrayList of Coordinate. + // Return null if the passing string is null or the Coordinate is 0. + private ArrayList splitCoordinate(String str) { + if (str == null) return null; + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(str); + ArrayList coordinateList = new ArrayList(); + for (String s : splitter) { + Coordinate coordinate = strToCoordinate(s); + if (coordinate != null) coordinateList.add(coordinate); + } + if (coordinateList.size() == 0) return null; + return coordinateList; + } + + // Parses a string (ex: "500x500") to Coordinate object. + // Return null if the passing string is null. + private Coordinate strToCoordinate(String str) { + if (str == null) return null; + + int pos = str.indexOf('x'); + if (pos != -1) { + String x = str.substring(0, pos); + String y = str.substring(pos + 1); + return new Coordinate(Integer.parseInt(x), + Integer.parseInt(y)); + } + Log.e(TAG, "Invalid Coordinate parameter string=" + str); + return null; + } + /* ### QC ADD-ONS: END */ }; } diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 1174cb6a2692..9f83b986ba5b 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -143,6 +143,7 @@ protected List getFullDynamicSensorList() { @Override protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) { + android.util.SeempLog.record_sensor_rate(381, sensor, delayUs); if (listener == null || sensor == null) { Log.e(TAG, "sensor or listener is null"); return false; @@ -161,6 +162,17 @@ protected boolean registerListenerImpl(SensorEventListener listener, Sensor sens + "the sensor listeners size has exceeded the maximum limit " + MAX_LISTENER_COUNT); } + if (sensor.getType() == Sensor.TYPE_SIGNIFICANT_MOTION) { + String pkgName = mContext.getPackageName(); + for (String blockedPkgName : mContext.getResources().getStringArray( + com.android.internal.R.array.config_blockPackagesSensorDrain)) { + if (pkgName.equals(blockedPkgName)) { + Log.w(TAG, "Preventing " + pkgName + "from draining battery using " + + "significant motion sensor"); + return false; + } + } + } // Invariants to preserve: // - one Looper per SensorEventListener @@ -190,6 +202,7 @@ protected boolean registerListenerImpl(SensorEventListener listener, Sensor sens /** @hide */ @Override protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { + android.util.SeempLog.record_sensor(382, sensor); // Trigger Sensors should use the cancelTriggerSensor call. if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { return; diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 04e9246b994e..43f3e9fcedf3 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -463,6 +463,10 @@ public abstract void createCaptureSession(@NonNull List outputs, @NonNull CameraCaptureSession.StateCallback callback, @Nullable Handler handler) throws CameraAccessException; + /** @hide */ + public abstract void setVendorStreamConfigMode(int index) + throws CameraAccessException; + /** *

Create a new camera capture session by providing the target output set of Surfaces and * its corresponding surface configuration to the camera device.

diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 7ebe0f9a8d8d..87058848360b 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemService; +import android.app.ActivityThread; import android.content.Context; import android.hardware.CameraInfo; import android.hardware.CameraStatus; @@ -39,6 +40,7 @@ import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemProperties; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; @@ -910,8 +912,34 @@ public String[] getCameraIdList() { // Try to make sure we have an up-to-date list of camera devices. connectCameraServiceLocked(); + boolean exposeAuxCamera = true; + String packageName = ActivityThread.currentOpPackageName(); + String packageList = SystemProperties.get("vendor.camera.aux.packagelist"); + String packageBlacklist = SystemProperties.get("vendor.camera.aux.packageblacklist"); + if (packageList.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageList); + exposeAuxCamera = false; + for (String str : splitter) { + if (packageName.equals(str)) { + exposeAuxCamera = true; + break; + } + } + } else if (packageBlacklist.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageBlacklist); + exposeAuxCamera = true; + for (String str : splitter) { + if (packageName.equals(str)) { + exposeAuxCamera = false; + break; + } + } + } int idCount = 0; for (int i = 0; i < mDeviceStatus.size(); i++) { + if(!exposeAuxCamera && (i == 2)) break; int status = mDeviceStatus.valueAt(i); if (status == ICameraServiceListener.STATUS_NOT_PRESENT || status == ICameraServiceListener.STATUS_ENUMERATING) continue; @@ -920,6 +948,7 @@ public String[] getCameraIdList() { cameraIds = new String[idCount]; idCount = 0; for (int i = 0; i < mDeviceStatus.size(); i++) { + if(!exposeAuxCamera && (i == 2)) break; int status = mDeviceStatus.valueAt(i); if (status == ICameraServiceListener.STATUS_NOT_PRESENT || status == ICameraServiceListener.STATUS_ENUMERATING) continue; @@ -1101,6 +1130,42 @@ private void updateCallbackLocked(AvailabilityCallback callback, Executor execut } private void onStatusChangedLocked(int status, String id) { + /* Force to ignore the last mono/aux camera status update + * if the package name does not falls in this bucket + */ + boolean exposeMonoCamera = true; + String packageName = ActivityThread.currentOpPackageName(); + String packageList = SystemProperties.get("vendor.camera.aux.packagelist"); + String packageBlacklist = SystemProperties.get("vendor.camera.aux.packageblacklist"); + if (packageList.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageList); + exposeMonoCamera = false; + for (String str : splitter) { + if (packageName.equals(str)) { + exposeMonoCamera = true; + break; + } + } + } else if (packageBlacklist.length() > 0) { + TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(','); + splitter.setString(packageBlacklist); + exposeMonoCamera = true; + for (String str : splitter) { + if (packageName.equals(str)) { + exposeMonoCamera = false; + break; + } + } + } + + if (exposeMonoCamera == false) { + if (Integer.parseInt(id) >= 2) { + Log.w(TAG, "[soar.cts] ignore the status update of camera: " + id); + return; + } + } + if (DEBUG) { Log.v(TAG, String.format("Camera id %s has status changed to 0x%x", id, status)); diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index d967fbaf610c..e9ea496195bc 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -74,7 +74,7 @@ public class CameraDeviceImpl extends CameraDevice private final boolean DEBUG = false; private static final int REQUEST_ID_NONE = -1; - + private int customOpMode = 0; // TODO: guard every function with if (!mRemoteDevice) check (if it was closed) private ICameraDeviceUserWrapper mRemoteDevice; @@ -354,6 +354,10 @@ public void run() { } } + public void setVendorStreamConfigMode(int fpsrange) { + customOpMode = fpsrange; + } + @Override public String getId() { return mCameraId; @@ -467,6 +471,7 @@ public boolean configureStreamsChecked(InputConfiguration inputConfig, mConfiguredOutputs.put(streamId, outConfig); } } + operatingMode = (operatingMode | (customOpMode << 16)); if (sessionParams != null) { mRemoteDevice.endConfigure(operatingMode, sessionParams.getNativeCopy()); diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index 83a02285e720..1b28d614a7f2 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -521,9 +521,10 @@ private void releaseEGLContext() { clearState(); } - private void makeCurrent(EGLSurface surface) { + private void makeCurrent(EGLSurface surface) + throws LegacyExceptionUtils.BufferQueueAbandonedException { EGL14.eglMakeCurrent(mEGLDisplay, surface, surface, mEGLContext); - checkEglError("makeCurrent"); + checkEglDrawError("makeCurrent"); } private boolean swapBuffers(EGLSurface surface) @@ -557,6 +558,17 @@ private boolean swapBuffers(EGLSurface surface) } } + private void checkEglDrawError(String msg) + throws LegacyExceptionUtils.BufferQueueAbandonedException { + int error; + if ((error = EGL14.eglGetError()) == EGL14.EGL_BAD_NATIVE_WINDOW) { + throw new LegacyExceptionUtils.BufferQueueAbandonedException(); + } + if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) { + throw new IllegalStateException(msg + ": EGL error: 0x" + Integer.toHexString(error)); + } + } + private void checkEglError(String msg) { int error; if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) { @@ -709,8 +721,14 @@ public void configureSurfaces(Collection> surfaces) { if (mConversionSurfaces.size() > 0) { configureEGLPbufferSurfaces(mConversionSurfaces); } - makeCurrent((mSurfaces.size() > 0) ? mSurfaces.get(0).eglSurface : + + try { + makeCurrent((mSurfaces.size() > 0) ? mSurfaces.get(0).eglSurface : mConversionSurfaces.get(0).eglSurface); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping configuration... ", e); + } + initializeGLState(); mSurfaceTexture = new SurfaceTexture(getTextureId()); @@ -798,9 +816,9 @@ public void drawIntoSurfaces(CaptureCollector targetCollector) { } for (EGLSurfaceHolder holder : mConversionSurfaces) { if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) { - makeCurrent(holder.eglSurface); // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip try { + makeCurrent(holder.eglSurface); drawFrame(mSurfaceTexture, holder.width, holder.height, (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ? FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL); diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java index 1ee3c933b326..71d69e665411 100644 --- a/core/java/android/hardware/camera2/params/OutputConfiguration.java +++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java @@ -630,13 +630,7 @@ public int getSurfaceGroupId() { new Parcelable.Creator() { @Override public OutputConfiguration createFromParcel(Parcel source) { - try { - OutputConfiguration outputConfiguration = new OutputConfiguration(source); - return outputConfiguration; - } catch (Exception e) { - Log.e(TAG, "Exception creating OutputConfiguration from parcel", e); - return null; - } + return new OutputConfiguration(source); } @Override diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptor.java b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java index ea424e594081..893bde1e1430 100644 --- a/core/java/android/hardware/camera2/params/VendorTagDescriptor.java +++ b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java @@ -36,13 +36,7 @@ private VendorTagDescriptor(Parcel source) { new Parcelable.Creator() { @Override public VendorTagDescriptor createFromParcel(Parcel source) { - try { - VendorTagDescriptor vendorDescriptor = new VendorTagDescriptor(source); - return vendorDescriptor; - } catch (Exception e) { - Log.e(TAG, "Exception creating VendorTagDescriptor from parcel", e); - return null; - } + return new VendorTagDescriptor(source); } @Override diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java b/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java index 1f92f6d9ebf1..423020870869 100644 --- a/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java +++ b/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java @@ -36,13 +36,7 @@ private VendorTagDescriptorCache(Parcel source) { new Parcelable.Creator() { @Override public VendorTagDescriptorCache createFromParcel(Parcel source) { - try { - VendorTagDescriptorCache vendorDescriptorCache = new VendorTagDescriptorCache(source); - return vendorDescriptorCache; - } catch (Exception e) { - Log.e(TAG, "Exception creating VendorTagDescriptorCache from parcel", e); - return null; - } + return new VendorTagDescriptorCache(source); } @Override diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index b182fa2e8ad3..c426fd76ea02 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -764,6 +764,10 @@ public Pair getMinimumBrightnessCurve() { return mGlobal.getMinimumBrightnessCurve(); } + public void requestScreenMode(int modeId) { + mGlobal.requestScreenMode(modeId); + } + /** * Listens for changes in available display devices. */ diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index d968a3e942bb..b4e833d9ce44 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -596,6 +596,14 @@ public List getAmbientBrightnessStats() { } } + public void requestScreenMode(int modeId) { + try { + mDm.requestScreenMode(modeId); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub { @Override public void onDisplayEvent(int displayId, int event) { diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index b57599724ad5..2a97327cfe8f 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -116,4 +116,6 @@ interface IDisplayManager { // Get the minimum brightness curve. Curve getMinimumBrightnessCurve(); + + void requestScreenMode(int i); } diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index ebbfe1c26a9c..5055af0ddb39 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -790,7 +790,7 @@ public boolean isHardwareDetected() { throw e.rethrowFromSystemServer(); } } else { - Slog.w(TAG, "isFingerprintHardwareDetected(): Service not connected!"); + if (DEBUG) Slog.w(TAG, "isFingerprintHardwareDetected(): Service not connected!"); } return false; } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index d26c51628e22..22fd4f7d2db4 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -43,6 +43,7 @@ import android.os.IBinder; import android.os.ResultReceiver; import android.os.SystemClock; +import android.os.UserHandle; import android.provider.Settings; import android.text.InputType; import android.text.Layout; @@ -341,6 +342,23 @@ public class InputMethodService extends AbstractInputMethodService { private static final int BACK_DISPOSITION_MIN = BACK_DISPOSITION_DEFAULT; private static final int BACK_DISPOSITION_MAX = BACK_DISPOSITION_ADJUST_NOTHING; + int mVolumeKeyCursorControl = 0; + + /** + * @hide + */ + public static final int VOLUME_CURSOR_OFF = 0; + + /** + * @hide + */ + public static final int VOLUME_CURSOR_ON = 1; + + /** + * @hide + */ + public static final int VOLUME_CURSOR_ON_REVERSE = 2; + InputMethodManager mImm; int mTheme = 0; @@ -2222,6 +2240,26 @@ public boolean onKeyDown(int keyCode, KeyEvent event) { } return false; } + if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) { + mVolumeKeyCursorControl = Settings.System.getIntForUser(getContentResolver(), + Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0, UserHandle.USER_CURRENT_OR_SELF); + if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) { + sendDownUpKeyEvents((mVolumeKeyCursorControl == VOLUME_CURSOR_ON_REVERSE) + ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT); + return true; + } + return false; + } + if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) { + mVolumeKeyCursorControl = Settings.System.getIntForUser(getContentResolver(), + Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0, UserHandle.USER_CURRENT_OR_SELF); + if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) { + sendDownUpKeyEvents((mVolumeKeyCursorControl == VOLUME_CURSOR_ON_REVERSE) + ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT); + return true; + } + return false; + } return doMovementKey(keyCode, event, MOVEMENT_DOWN); } @@ -2272,6 +2310,15 @@ public boolean onKeyUp(int keyCode, KeyEvent event) { return handleBack(true); } } + if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP + || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + mVolumeKeyCursorControl = Settings.System.getIntForUser(getContentResolver(), + Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0, UserHandle.USER_CURRENT_OR_SELF); + if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) { + return true; + } + return false; + } return doMovementKey(keyCode, event, MOVEMENT_UP); } diff --git a/core/java/android/net/NetworkBadging.java b/core/java/android/net/NetworkBadging.java index c119b637140f..cd9ea88e5b76 100644 --- a/core/java/android/net/NetworkBadging.java +++ b/core/java/android/net/NetworkBadging.java @@ -21,13 +21,10 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; import android.net.wifi.WifiManager; -import android.view.View; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -96,34 +93,4 @@ private NetworkBadging() {} throw new IllegalArgumentException("Invalid signal level: " + signalLevel); } } - - /** - * Returns the badged wifi signal resource id for the given signal level. - * - *

This badged wifi signal resource should be displayed with the quality badge retrieved - * from {@link #getWifiBadgeResource(int)}. If there is no badge, - * {@link #getWifiBadgeResource(int)} should be used instead of this method. - * - * @param signalLevel The level returned by {@link WifiManager#calculateSignalLevel(int, int)} - * for a network. Must be between 0 and {@link WifiManager#RSSI_LEVELS}-1. - * @return the @DrawableRes for the icon - * @throws IllegalArgumentException for an invalid signal level - * @hide - */ - @DrawableRes private static int getBadgedWifiSignalResource(int signalLevel) { - switch (signalLevel) { - case 0: - return com.android.internal.R.drawable.ic_signal_wifi_badged_0_bars; - case 1: - return com.android.internal.R.drawable.ic_signal_wifi_badged_1_bar; - case 2: - return com.android.internal.R.drawable.ic_signal_wifi_badged_2_bars; - case 3: - return com.android.internal.R.drawable.ic_signal_wifi_badged_3_bars; - case 4: - return com.android.internal.R.drawable.ic_signal_wifi_badged_4_bars; - default: - throw new IllegalArgumentException("Invalid signal level: " + signalLevel); - } - } } diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 75fd77e70a1b..64fef4c8d2b3 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -54,6 +54,12 @@ public class NetworkPolicyManager { public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1; /** Allow metered network use in the background even when in data usage save mode. */ public static final int POLICY_ALLOW_METERED_BACKGROUND = 0x4; + /** Reject application network traffic on cellular network */ + public static final int POLICY_REJECT_ON_DATA = 0x10000; + /** Reject application network traffic on virtual private network */ + public static final int POLICY_REJECT_ON_VPN = 0x20000; + /** Reject application network traffic on wifi network */ + public static final int POLICY_REJECT_ON_WLAN = 0x8000; /* * Rules defining whether an uid has access to a network given its type (metered / non-metered). diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java index be2f9551daff..fcfb72035c19 100644 --- a/core/java/android/net/NetworkSpecifier.java +++ b/core/java/android/net/NetworkSpecifier.java @@ -17,7 +17,7 @@ package android.net; /** - * Describes specific properties of a network for use in a {@link NetworkRequest}. + * Describes specific properties of a requested network for use in a {@link NetworkRequest}. * * Applications cannot instantiate this class by themselves, but can obtain instances of * subclasses of this class via other APIs. @@ -49,4 +49,29 @@ public NetworkSpecifier() {} public void assertValidFromUid(int requestorUid) { // empty } + + /** + * Optional method which can be overridden by concrete implementations of NetworkSpecifier to + * perform any redaction of information from the NetworkSpecifier, e.g. if it contains + * sensitive information. The default implementation simply returns the object itself - i.e. + * no information is redacted. A concrete implementation may return a modified (copy) of the + * NetworkSpecifier, or even return a null to fully remove all information. + *

+ * This method is relevant to NetworkSpecifier objects used by agents - those are shared with + * apps by default. Some agents may store sensitive matching information in the specifier, + * e.g. a Wi-Fi SSID (which should not be shared since it may leak location). Those classes + * can redact to a null. Other agents use the Network Specifier to share public information + * with apps - those should not be redacted. + *

+ * The default implementation redacts no information. + * + * @return A NetworkSpecifier object to be passed along to the requesting app. + * + * @hide + */ + public NetworkSpecifier redact() { + // TODO (b/122160111): convert default to null once all platform NetworkSpecifiers + // implement this method. + return this; + } } diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index 6801618e6a68..b3bcf6f92be9 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -1,4 +1,7 @@ /* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution. + * * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,6 +34,7 @@ import android.nfc.INfcUnlockHandler; import android.nfc.ITagRemovedCallback; import android.nfc.INfcDta; import android.os.Bundle; +import android.os.IBinder; /** * @hide @@ -42,6 +46,7 @@ interface INfcAdapter INfcFCardEmulation getNfcFCardEmulationInterface(); INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg); INfcDta getNfcDtaInterface(in String pkg); + IBinder getNfcAdapterVendorInterface(in String vendor); int getState(); boolean disable(boolean saveState); boolean enable(); diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java index 78a9401a2abd..ce67061a084e 100644 --- a/core/java/android/nfc/cardemulation/AidGroup.java +++ b/core/java/android/nfc/cardemulation/AidGroup.java @@ -1,4 +1,7 @@ /* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution. + * * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,7 +40,7 @@ * * @hide */ -public final class AidGroup implements Parcelable { +public class AidGroup implements Parcelable { /** * The maximum number of AIDs that can be present in any one group. */ @@ -45,9 +48,9 @@ public final class AidGroup implements Parcelable { static final String TAG = "AidGroup"; - final List aids; - final String category; - final String description; + protected List aids; + protected String category; + protected String description; /** * Creates a new AidGroup object. diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index 218e4f223549..a06f17608325 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -1,4 +1,7 @@ /* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution. + * * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -48,53 +51,53 @@ /** * @hide */ -public final class ApduServiceInfo implements Parcelable { +public class ApduServiceInfo implements Parcelable { static final String TAG = "ApduServiceInfo"; /** * The service that implements this */ - final ResolveInfo mService; + protected ResolveInfo mService; /** * Description of the service */ - final String mDescription; + protected String mDescription; /** * Whether this service represents AIDs running on the host CPU */ - final boolean mOnHost; + protected boolean mOnHost; /** * Mapping from category to static AID group */ - final HashMap mStaticAidGroups; + protected HashMap mStaticAidGroups; /** * Mapping from category to dynamic AID group */ - final HashMap mDynamicAidGroups; + protected HashMap mDynamicAidGroups; /** * Whether this service should only be started when the device is unlocked. */ - final boolean mRequiresDeviceUnlock; + protected boolean mRequiresDeviceUnlock; /** * The id of the service banner specified in XML. */ - final int mBannerResourceId; + protected int mBannerResourceId; /** * The uid of the package the service belongs to */ - final int mUid; + protected int mUid; /** * Settings Activity for this service */ - final String mSettingsActivityName; + protected String mSettingsActivityName; /** * @hide diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java index 9b5bda885abd..eef226ccf812 100644 --- a/core/java/android/nfc/tech/MifareClassic.java +++ b/core/java/android/nfc/tech/MifareClassic.java @@ -1,4 +1,6 @@ /* + * Copyright (C) 2015 NXP Semiconductors + * The original Work has been changed by NXP Semiconductors. * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -173,6 +175,10 @@ public MifareClassic(Tag tag) throws RemoteException { mType = TYPE_CLASSIC; mSize = SIZE_4K; break; + case 0x19: + mType = TYPE_CLASSIC; + mSize = SIZE_2K; + break; case 0x28: mType = TYPE_CLASSIC; mSize = SIZE_1K; diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java index 88730f9af3df..b7fa455e3880 100644 --- a/core/java/android/nfc/tech/NfcA.java +++ b/core/java/android/nfc/tech/NfcA.java @@ -1,4 +1,6 @@ /* + * Copyright (C) 2015 NXP Semiconductors + * The original Work has been changed by NXP Semiconductors. * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -66,8 +68,15 @@ public static NfcA get(Tag tag) { /** @hide */ public NfcA(Tag tag) throws RemoteException { super(tag, TagTechnology.NFC_A); - Bundle extras = tag.getTechExtras(TagTechnology.NFC_A); - mSak = extras.getShort(EXTRA_SAK); + Bundle extras; + mSak = 0; + if(tag.hasTech(TagTechnology.MIFARE_CLASSIC)) + { + extras = tag.getTechExtras(TagTechnology.MIFARE_CLASSIC); + mSak = extras.getShort(EXTRA_SAK); + } + extras = tag.getTechExtras(TagTechnology.NFC_A); + mSak |= extras.getShort(EXTRA_SAK); mAtqa = extras.getByteArray(EXTRA_ATQA); } diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index 0fef78d1f4ba..3385d40fc742 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -294,7 +294,14 @@ private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean r } else { throw e; } - } finally { + } catch (RuntimeException e) { + if (sShouldDefuse && (e.getCause() instanceof ClassNotFoundException)) { + Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); + map.erase(); + } else { + throw e; + } + }finally { mMap = map; if (recycleParcel) { recycleParcel(parcelledData); diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index 954071a0ee97..c87e476d6b04 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -156,6 +156,13 @@ public class BatteryManager { @SystemApi public static final String EXTRA_EVENT_TIMESTAMP = "android.os.extra.EVENT_TIMESTAMP"; + /** + * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}: + * boolean value to detect fast charging + * {@hide} + */ + public static final String EXTRA_DASH_CHARGER = "dash_charger"; + // values for "status" field in the ACTION_BATTERY_CHANGED Intent public static final int BATTERY_STATUS_UNKNOWN = Constants.BATTERY_STATUS_UNKNOWN; public static final int BATTERY_STATUS_CHARGING = Constants.BATTERY_STATUS_CHARGING; diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 8e8565c3574c..4db8d1ea64d5 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -740,6 +740,8 @@ private boolean execTransact(int code, long dataObj, long replyObj, Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); } } else { + // Clear the parcel before writing the exception + reply.setDataSize(0); reply.setDataPosition(0); reply.writeException(e); } diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index f86a6f6ce7d2..ace71ca49cd8 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -30,7 +30,11 @@ import dalvik.system.VMRuntime; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Information about the current build, extracted from system properties. @@ -928,6 +932,7 @@ public static class VERSION_CODES { /** The type of build, like "user" or "eng". */ public static final String TYPE = getString("ro.build.type"); + private static String TYPE_FOR_APPS = parseBuildTypeFromFingerprint(); /** Comma-separated tags describing the build, like "unsigned,debug". */ public static final String TAGS = getString("ro.build.tags"); @@ -935,6 +940,10 @@ public static class VERSION_CODES { /** A string that uniquely identifies this build. Do not attempt to parse this value. */ public static final String FINGERPRINT = deriveFingerprint(); + /** @hide */ + public static final String AOSIP_FINGERPRINT = SystemProperties.get("ro.aosip.fingerprint", + deriveFingerprint()); + /** * Some devices split the fingerprint components between multiple * partitions, so we might derive the fingerprint at runtime. @@ -954,6 +963,44 @@ private static String deriveFingerprint() { return finger; } + /* + * Some apps like to compare the build type embedded in fingerprint + * to the actual build type. As the fingerprint in our case is almost + * always hardcoded to the stock ROM fingerprint, provide that instead + * of the actual one if possible. + */ + private static String parseBuildTypeFromFingerprint() { + final String fingerprint = SystemProperties.get("ro.build.fingerprint"); + if (TextUtils.isEmpty(fingerprint)) { + return null; + } + Pattern fingerprintPattern = + Pattern.compile("(.*)\\/(.*)\\/(.*):(.*)\\/(.*)\\/(.*):(.*)\\/(.*)"); + Matcher matcher = fingerprintPattern.matcher(fingerprint); + return matcher.matches() ? matcher.group(7) : null; + } + + /** @hide */ + public static void adjustBuildTypeIfNeeded() { + if (Process.isApplicationUid(Process.myUid()) && !TextUtils.isEmpty(TYPE_FOR_APPS)) { + try { + // This is sick. TYPE is final (which can't be changed because it's an API + // guarantee), but we have to reassign it. Resort to reflection to unset the + // final modifier, change the value and restore the final modifier afterwards. + Field typeField = Build.class.getField("TYPE"); + Field accessFlagsField = Field.class.getDeclaredField("accessFlags"); + accessFlagsField.setAccessible(true); + int currentFlags = accessFlagsField.getInt(typeField); + accessFlagsField.setInt(typeField, currentFlags & ~Modifier.FINAL); + typeField.set(null, TYPE_FOR_APPS); + accessFlagsField.setInt(typeField, currentFlags); + accessFlagsField.setAccessible(false); + } catch (Exception e) { + // shouldn't happen, but we don't want to crash the app even if it does happen + } + } + } + /** * Ensure that raw fingerprint system property is defined. If it was derived * dynamically by {@link #deriveFingerprint()} this is where we push the diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl index 827170144dea..3d2d4fbcf865 100644 --- a/core/java/android/os/IDeviceIdleController.aidl +++ b/core/java/android/os/IDeviceIdleController.aidl @@ -45,4 +45,6 @@ interface IDeviceIdleController { void exitIdle(String reason); boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener); void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener); + int getIdleStateDetailed(); + int getLightIdleStateDetailed(); } diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 31dbafad62e3..c5319d0b70aa 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -450,4 +450,11 @@ interface INetworkManagementService void setAllowOnlyVpnForUids(boolean enable, in UidRange[] uidRanges); boolean isNetworkRestricted(int uid); + + /** + * Restrict UID from accessing mobile data/vpn/wifi + */ + void restrictAppOnData(int uid, boolean restrict); + void restrictAppOnVpn(int uid, boolean restrict); + void restrictAppOnWlan(int uid, boolean restrict); } diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 13e4e38df5f6..59444b26c06f 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -68,4 +68,11 @@ interface IPowerManager // controls whether PowerManager should doze after the screen turns off or not void setDozeAfterScreenOff(boolean on); + + // update the uids being synchronized by network socket request manager + void updateBlockedUids(int uid, boolean isBlocked); + + // temporarily overrides the button brightness settings to allow the user to + // see the effect of a settings change without applying it immediately + void setTemporaryButtonBrightnessSettingOverride(int brightness); } diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 87e1b7d21f53..fbf28d7c2add 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -26,6 +26,7 @@ import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -171,18 +172,18 @@ public String toLanguageTags() { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

* * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -190,10 +191,10 @@ public LocaleList(@NonNull Locale... list) { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -201,7 +202,7 @@ public LocaleList(@NonNull Locale... list) { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 460f12510d45..2dfebf76b28c 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -2793,65 +2793,67 @@ public final Parcelable.Creator readParcelableCreator(ClassLoader loader) { return null; } Parcelable.Creator creator; + HashMap> map; synchronized (mCreators) { - HashMap> map = mCreators.get(loader); + map = mCreators.get(loader); if (map == null) { map = new HashMap<>(); mCreators.put(loader, map); } creator = map.get(name); - if (creator == null) { - try { - // If loader == null, explicitly emulate Class.forName(String) "caller - // classloader" behavior. - ClassLoader parcelableClassLoader = - (loader == null ? getClass().getClassLoader() : loader); - // Avoid initializing the Parcelable class until we know it implements - // Parcelable and has the necessary CREATOR field. http://b/1171613. - Class parcelableClass = Class.forName(name, false /* initialize */, - parcelableClassLoader); - if (!Parcelable.class.isAssignableFrom(parcelableClass)) { - throw new BadParcelableException("Parcelable protocol requires subclassing " - + "from Parcelable on class " + name); - } - Field f = parcelableClass.getField("CREATOR"); - if ((f.getModifiers() & Modifier.STATIC) == 0) { - throw new BadParcelableException("Parcelable protocol requires " - + "the CREATOR object to be static on class " + name); - } - Class creatorType = f.getType(); - if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) { - // Fail before calling Field.get(), not after, to avoid initializing - // parcelableClass unnecessarily. - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + "CREATOR on class " + name); - } - creator = (Parcelable.Creator) f.get(null); - } - catch (IllegalAccessException e) { - Log.e(TAG, "Illegal access when unmarshalling: " + name, e); - throw new BadParcelableException( - "IllegalAccessException when unmarshalling: " + name); - } - catch (ClassNotFoundException e) { - Log.e(TAG, "Class not found when unmarshalling: " + name, e); - throw new BadParcelableException( - "ClassNotFoundException when unmarshalling: " + name); - } - catch (NoSuchFieldException e) { - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + "CREATOR on class " + name); - } - if (creator == null) { - throw new BadParcelableException("Parcelable protocol requires a " - + "non-null Parcelable.Creator object called " - + "CREATOR on class " + name); - } + } + if (creator != null) { + return creator; + } - map.put(name, creator); + try { + // If loader == null, explicitly emulate Class.forName(String) "caller + // classloader" behavior. + ClassLoader parcelableClassLoader = + (loader == null ? getClass().getClassLoader() : loader); + // Avoid initializing the Parcelable class until we know it implements + // Parcelable and has the necessary CREATOR field. http://b/1171613. + Class parcelableClass = Class.forName(name, false /* initialize */, + parcelableClassLoader); + if (!Parcelable.class.isAssignableFrom(parcelableClass)) { + throw new BadParcelableException("Parcelable protocol requires subclassing " + + "from Parcelable on class " + name); + } + Field f = parcelableClass.getField("CREATOR"); + if ((f.getModifiers() & Modifier.STATIC) == 0) { + throw new BadParcelableException("Parcelable protocol requires " + + "the CREATOR object to be static on class " + name); } + Class creatorType = f.getType(); + if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) { + // Fail before calling Field.get(), not after, to avoid initializing + // parcelableClass unnecessarily. + throw new BadParcelableException("Parcelable protocol requires a " + + "Parcelable.Creator object called " + + "CREATOR on class " + name); + } + creator = (Parcelable.Creator) f.get(null); + } catch (IllegalAccessException e) { + Log.e(TAG, "Illegal access when unmarshalling: " + name, e); + throw new BadParcelableException( + "IllegalAccessException when unmarshalling: " + name); + } catch (ClassNotFoundException e) { + Log.e(TAG, "Class not found when unmarshalling: " + name, e); + throw new BadParcelableException( + "ClassNotFoundException when unmarshalling: " + name); + } catch (NoSuchFieldException e) { + throw new BadParcelableException("Parcelable protocol requires a " + + "Parcelable.Creator object called " + + "CREATOR on class " + name); + } + if (creator == null) { + throw new BadParcelableException("Parcelable protocol requires a " + + "non-null Parcelable.Creator object called " + + "CREATOR on class " + name); + } + + synchronized (mCreators) { + map.put(name, creator); } return creator; diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 9c258487447e..d3fb1fbb8e1e 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -415,6 +415,16 @@ public final class PowerManager { */ public static final String REBOOT_RECOVERY = "recovery"; + /** + * The value to pass as the 'reason' argument to reboot() to reboot into + * bootloader mode if you need to get to the choppa (cit) + *

+ * Requires {@link android.Manifest.permission#REBOOT}). + *

+ * @hide + */ + public static final String REBOOT_BOOTLOADER = "bootloader"; + /** * The value to pass as the 'reason' argument to reboot() to reboot into * recovery mode for applying system updates. diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java index 24c9c9177360..25347f5a2ed2 100644 --- a/core/java/android/os/UpdateEngine.java +++ b/core/java/android/os/UpdateEngine.java @@ -253,6 +253,17 @@ public void resetStatus() { } } + /** + * @hide + */ + public void setPerformanceMode(boolean enable) { + try { + mUpdateEngine.setPerformanceMode(enable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Unbinds the last bound callback function. */ diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index d493ccebf531..e41ecf8f901a 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -48,6 +48,8 @@ public class DiskInfo implements Parcelable { public static final int FLAG_DEFAULT_PRIMARY = 1 << 1; public static final int FLAG_SD = 1 << 2; public static final int FLAG_USB = 1 << 3; + public static final int FLAG_EMMC = 1 << 4; + public static final int FLAG_NON_REMOVABLE = 1 << 5; public final String id; public final int flags; @@ -140,6 +142,10 @@ public boolean isUsb() { return (flags & FLAG_USB) != 0; } + public boolean isNonRemovable() { + return (flags & FLAG_NON_REMOVABLE) != 0; + } + @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl index 55a202fd3a66..49bc9e4d8d07 100644 --- a/core/java/android/os/storage/IStorageManager.aidl +++ b/core/java/android/os/storage/IStorageManager.aidl @@ -187,4 +187,5 @@ interface IStorageManager { void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) = 78; void runIdleMaintenance() = 79; void abortIdleMaintenance() = 80; + void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 81; } diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index fd5a22a9c551..f68d842161d1 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -249,16 +249,21 @@ public UserHandle getOwner() { } /** - * Parse and return volume UUID as FAT volume ID, or return -1 if unable to + * Parse and return volume UUID as volume ID, or return -1 if unable to * parse or UUID is unknown. * @hide */ - public int getFatVolumeId() { - if (mFsUuid == null || mFsUuid.length() != 9) { + public int getVolumeId() { + String id = mFsUuid; + if (id == null) { return -1; } + id = id.replace("-", ""); + if (id.length() > 8) { + id = id.substring(0, 8); + } try { - return (int) Long.parseLong(mFsUuid.replace("-", ""), 16); + return (int) Long.parseLong(id, 16); } catch (NumberFormatException e) { return -1; } diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 8d4c3c3d3e68..8c7750242ef3 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -312,7 +312,9 @@ public File getPathForUser(int userId) { * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}. */ public File getInternalPathForUser(int userId) { - if (type == TYPE_PUBLIC) { + if (path == null) { + return null; + } else if (type == TYPE_PUBLIC) { // TODO: plumb through cleaner path from vold return new File(path.replace("/storage/", "/mnt/media_rw/")); } else { diff --git a/core/java/android/pocket/IPocketCallback.aidl b/core/java/android/pocket/IPocketCallback.aidl new file mode 100644 index 000000000000..53e5412f89be --- /dev/null +++ b/core/java/android/pocket/IPocketCallback.aidl @@ -0,0 +1,24 @@ +/** + * Copyright (C) 2016 The ParanoidAndroid Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.pocket; + +/** @hide */ +interface IPocketCallback { + + // notify when pocket state changes. + void onStateChanged(boolean isDeviceInPocket, int reason); + +} \ No newline at end of file diff --git a/core/java/android/pocket/IPocketService.aidl b/core/java/android/pocket/IPocketService.aidl new file mode 100644 index 000000000000..783465774207 --- /dev/null +++ b/core/java/android/pocket/IPocketService.aidl @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2016 The ParanoidAndroid Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.pocket; + +import android.pocket.IPocketCallback; + +/** @hide */ +interface IPocketService { + + // add callback to get notified about pocket state. + void addCallback(IPocketCallback callback); + + // remove callback and stop getting notified about pocket state. + void removeCallback(IPocketCallback callback); + + // notify pocket service about intercative state changed. + // @see com.android.policy.PhoneWindowManager + void onInteractiveChanged(boolean interactive); + + // external processes can request changing listening state. + void setListeningExternal(boolean listen); + + // check if device is in pocket. + boolean isDeviceInPocket(); + + // Custom methods + void setPocketLockVisible(boolean visible); + boolean isPocketLockVisible(); + +} \ No newline at end of file diff --git a/core/java/android/pocket/PocketConstants.java b/core/java/android/pocket/PocketConstants.java new file mode 100644 index 000000000000..f0d08a272375 --- /dev/null +++ b/core/java/android/pocket/PocketConstants.java @@ -0,0 +1,25 @@ +package android.pocket; + +/** + * This class contains global pocket setup constants. + * @author Carlo Savignano + * @hide + */ + +public class PocketConstants { + + public static final boolean DEBUG = false; + public static final boolean DEBUG_SPEW = false; + + /** + * Whether to use proximity sensor to evaluate pocket state. + */ + public static final boolean ENABLE_PROXIMITY_JUDGE = true; + + /** + * Whether to use light sensor to evaluate pocket state. + */ + public static final boolean ENABLE_LIGHT_JUDGE = true; + + +} diff --git a/core/java/android/pocket/PocketManager.java b/core/java/android/pocket/PocketManager.java new file mode 100644 index 000000000000..22b60696289b --- /dev/null +++ b/core/java/android/pocket/PocketManager.java @@ -0,0 +1,233 @@ +/** + * Copyright (C) 2016 The ParanoidAndroid Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.pocket; + +import android.content.Context; +import android.os.Handler; +import android.os.PowerManager; +import android.os.RemoteException; +import android.os.SystemClock; +import android.text.format.DateUtils; +import android.util.Log; +import android.util.Slog; + +/** + * A class that coordinates listening for pocket state. + *

+ * Use {@link android.content.Context#getSystemService(java.lang.String)} + * with argument {@link android.content.Context#POCKET_SERVICE} to get + * an instance of this class. + * + * Usage: import and create a final {@link IPocketCallback.Stub()} and implement your logic in + * {@link IPocketCallback#onStateChanged(boolean, int)}. Then add your callback to the pocket manager + * + * // define a final callback + * private final IPocketCallback mCallback = new IPocketCallback.Stub() { + * + * @Override + * public void onStateChanged(boolean isDeviceInPocket, int reason) { + * // Your method to handle logic outside of this callback, ideally with a handler + * // posting on UI Thread for view hierarchy operations or with its own background thread. + * handlePocketStateChanged(isDeviceInPocket, reason); + * } + * + * } + * + * // add callback to pocket manager + * private void addCallback() { + * PocketManager manager = (PocketManager) context.getSystemService(Context.POCKET_SERVICE); + * manager.addCallback(mCallback); + * } + * + * @author Carlo Savignano + * @hide + */ +public class PocketManager { + + private static final String TAG = PocketManager.class.getSimpleName(); + static final boolean DEBUG = false; + + /** + * Whether {@link IPocketCallback#onStateChanged(boolean, int)} + * was fired because of the sensor. + * @see PocketService#handleDispatchCallbacks() + */ + public static final int REASON_SENSOR = 0; + + /** + * Whether {@link IPocketCallback#onStateChanged(boolean, int)} + * was fired because of an error while accessing service. + * @see #addCallback(IPocketCallback) + * @see #removeCallback(IPocketCallback) + */ + public static final int REASON_ERROR = 1; + + /** + * Whether {@link IPocketCallback#onStateChanged(boolean, int)} + * was fired because of a needed reset. + * @see PocketService#binderDied() + */ + public static final int REASON_RESET = 2; + + private Context mContext; + private IPocketService mService; + private PowerManager mPowerManager; + private Handler mHandler; + private boolean mPocketViewTimerActive; + + public PocketManager(Context context, IPocketService service) { + mContext = context; + mService = service; + if (mService == null) { + Slog.v(TAG, "PocketService was null"); + } + mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + mHandler = new Handler(); + } + + /** + * Add pocket state callback. + * @see PocketService#handleRemoveCallback(IPocketCallback) + */ + public void addCallback(final IPocketCallback callback) { + if (mService != null) try { + mService.addCallback(callback); + } catch (RemoteException e1) { + Log.w(TAG, "Remote exception in addCallback: ", e1); + if (callback != null){ + try { + callback.onStateChanged(false, REASON_ERROR); + } catch (RemoteException e2) { + Log.w(TAG, "Remote exception in callback.onPocketStateChanged: ", e2); + } + } + } + } + + /** + * Remove pocket state callback. + * @see PocketService#handleAddCallback(IPocketCallback) + */ + public void removeCallback(final IPocketCallback callback) { + if (mService != null) try { + mService.removeCallback(callback); + } catch (RemoteException e1) { + Log.w(TAG, "Remote exception in removeCallback: ", e1); + if (callback != null){ + try { + callback.onStateChanged(false, REASON_ERROR); + } catch (RemoteException e2) { + Log.w(TAG, "Remote exception in callback.onPocketStateChanged: ", e2); + } + } + } + } + + /** + * Notify service about device interactive state changed. + * {@link PhoneWindowManager#startedWakingUp()} + * {@link PhoneWindowManager#startedGoingToSleep(int)} + */ + public void onInteractiveChanged(boolean interactive) { + boolean isPocketViewShowing = (interactive && isDeviceInPocket()); + synchronized (mPocketLockTimeout) { + if (mPocketViewTimerActive != isPocketViewShowing) { + if (isPocketViewShowing) { + if (DEBUG) Log.v(TAG, "Setting pocket timer"); + mHandler.removeCallbacks(mPocketLockTimeout); // remove any pending requests + mHandler.postDelayed(mPocketLockTimeout, 3 * DateUtils.SECOND_IN_MILLIS); + mPocketViewTimerActive = true; + } else { + if (DEBUG) Log.v(TAG, "Clearing pocket timer"); + mHandler.removeCallbacks(mPocketLockTimeout); + mPocketViewTimerActive = false; + } + } + } + if (mService != null) try { + mService.onInteractiveChanged(interactive); + } catch (RemoteException e) { + Log.w(TAG, "Remote exception in addCallback: ", e); + } + } + + /** + * Request listening state change by, but not limited to, external process. + * @see PocketService#handleSetListeningExternal(boolean) + */ + public void setListeningExternal(boolean listen) { + if (mService != null) try { + mService.setListeningExternal(listen); + } catch (RemoteException e) { + Log.w(TAG, "Remote exception in setListeningExternal: ", e); + } + // Clear timeout when user hides pocket lock with long press power. + if (mPocketViewTimerActive && !listen) { + if (DEBUG) Log.v(TAG, "Clearing pocket timer due to override"); + mHandler.removeCallbacks(mPocketLockTimeout); + mPocketViewTimerActive = false; + } + } + + /** + * Return whether device is in pocket. + * @see PocketService#isDeviceInPocket() + * @return + */ + public boolean isDeviceInPocket() { + if (mService != null) try { + return mService.isDeviceInPocket(); + } catch (RemoteException e) { + Log.w(TAG, "Remote exception in isDeviceInPocket: ", e); + } + return false; + } + + class PocketLockTimeout implements Runnable { + @Override + public void run() { + mPowerManager.goToSleep(SystemClock.uptimeMillis()); + mPocketViewTimerActive = false; + } + } + + /** Custom methods **/ + + public void setPocketLockVisible(boolean visible) { + if (!visible){ + if (DEBUG) Log.v(TAG, "Clearing pocket timer"); + mHandler.removeCallbacks(mPocketLockTimeout); + mPocketViewTimerActive = false; + } + if (mService != null) try { + mService.setPocketLockVisible(visible); + } catch (RemoteException e) { + Log.w(TAG, "Remote exception in setPocketLockVisible: ", e); + } + } + + public boolean isPocketLockVisible() { + if (mService != null) try { + return mService.isPocketLockVisible(); + } catch (RemoteException e) { + Log.w(TAG, "Remote exception in isPocketLockVisible: ", e); + } + return false; + } + + private PocketLockTimeout mPocketLockTimeout = new PocketLockTimeout(); + +} diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java index 3d57b4db2598..035b280e041f 100644 --- a/core/java/android/preference/DialogPreference.java +++ b/core/java/android/preference/DialogPreference.java @@ -285,6 +285,22 @@ protected void onClick() { * @param state Optional instance state to restore on the dialog */ protected void showDialog(Bundle state) { + // Create the dialog + final Dialog dialog = mDialog = createDialog(); + if (state != null) { + dialog.onRestoreInstanceState(state); + } + if (needInputMethod()) { + requestInputMethod(dialog); + } + dialog.setOnDismissListener(this); + dialog.show(); + } + + /** + * @hide + */ + protected Dialog createDialog() { Context context = getContext(); mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE; @@ -307,16 +323,7 @@ protected void showDialog(Bundle state) { getPreferenceManager().registerOnActivityDestroyListener(this); - // Create the dialog - final Dialog dialog = mDialog = mBuilder.create(); - if (state != null) { - dialog.onRestoreInstanceState(state); - } - if (needInputMethod()) { - requestInputMethod(dialog); - } - dialog.setOnDismissListener(this); - dialog.show(); + return mBuilder.create(); } /** diff --git a/core/java/android/preference/MultiSelectListPreference.java b/core/java/android/preference/MultiSelectListPreference.java index 138bd8780837..721519b4a059 100644 --- a/core/java/android/preference/MultiSelectListPreference.java +++ b/core/java/android/preference/MultiSelectListPreference.java @@ -220,7 +220,7 @@ protected void onDialogClosed(boolean positiveResult) { @Override protected Object onGetDefaultValue(TypedArray a, int index) { final CharSequence[] defaultValues = a.getTextArray(index); - final int valueCount = defaultValues.length; + final int valueCount = defaultValues != null ? defaultValues.length : 0; final Set result = new HashSet(); for (int i = 0; i < valueCount; i++) { diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 4306bc47f2b5..32760d6e7a67 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -1543,6 +1543,14 @@ protected void onPrepareForRemoval() { public void setDefaultValue(Object defaultValue) { mDefaultValue = defaultValue; } + + /** + * Returns whether the preference can be found in persistent storage + * @hide + */ + protected boolean isPersisted() { + return getSharedPreferences().contains(mKey); + } private void dispatchSetInitialValue() { if (getPreferenceDataStore() != null) { @@ -1552,7 +1560,7 @@ private void dispatchSetInitialValue() { // By now, we know if we are persistent. final boolean shouldPersist = shouldPersist(); - if (!shouldPersist || !getSharedPreferences().contains(mKey)) { + if (!shouldPersist || !isPersisted()) { if (mDefaultValue != null) { onSetInitialValue(false, mDefaultValue); } diff --git a/core/java/android/preference/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java index a76bb0953cc1..c5cc6076e04e 100644 --- a/core/java/android/preference/RingtonePreference.java +++ b/core/java/android/preference/RingtonePreference.java @@ -32,6 +32,7 @@ *

* If the user chooses the "Default" item, the saved string will be one of * {@link System#DEFAULT_RINGTONE_URI}, + * {@link System#DEFAULT_RINGTONE2_URI}, * {@link System#DEFAULT_NOTIFICATION_URI}, or * {@link System#DEFAULT_ALARM_ALERT_URI}. If the user chooses the "Silent" * item, the saved string will be an empty string. diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index 0ed252667533..295c4023fe42 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -62,6 +62,7 @@ public interface Callback { private final NotificationManager mNotificationManager; private final int mStreamType; private final int mMaxStreamVolume; + private final boolean mVoiceCapable; private boolean mAffectedByRingerMode; private boolean mNotificationOrRing; private final Receiver mReceiver = new Receiver(); @@ -129,6 +130,8 @@ public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callbac } } mDefaultUri = defaultUri; + mVoiceCapable = context.getResources().getBoolean( + com.android.internal.R.bool.config_voice_capable); } private static boolean isNotificationOrRing(int stream) { @@ -143,6 +146,11 @@ private static boolean isMediaStream(int stream) { return stream == AudioManager.STREAM_MUSIC; } + private boolean isNotificationStreamLinked() { + return mVoiceCapable && Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; + } + public void setSeekBar(SeekBar seekBar) { if (mSeekBar != null) { mSeekBar.setOnSeekBarChangeListener(null); @@ -170,13 +178,19 @@ protected void updateSeekBar() { mSeekBar.setProgress(mLastAudibleStreamVolume, true); } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { mSeekBar.setProgress(0, true); + mSeekBar.setEnabled(isSeekBarEnabled()); } else if (mMuted) { mSeekBar.setProgress(0, true); } else { + mSeekBar.setEnabled(isSeekBarEnabled()); mSeekBar.setProgress(mLastProgress > -1 ? mLastProgress : mOriginalStreamVolume, true); } } + private boolean isSeekBarEnabled() { + return !(mStreamType == AudioManager.STREAM_NOTIFICATION && isNotificationStreamLinked()); + } + @Override public boolean handleMessage(Message msg) { switch (msg.what) { @@ -287,7 +301,7 @@ public void revertVolume() { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { - if (fromTouch) { + if (fromTouch && isSeekBarEnabled()) { postSetVolume(progress); } if (mCallback != null) { @@ -463,7 +477,8 @@ public void onReceive(Context context, Intent intent) { } private void updateVolumeSlider(int streamType, int streamValue) { - final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType) + final boolean streamMatch = mNotificationOrRing && isNotificationStreamLinked() + ? isNotificationOrRing(streamType) : (streamType == mStreamType); if (mSeekBar != null && streamMatch && streamValue != -1) { final boolean muted = mAudioManager.isStreamMute(mStreamType) diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java index 7d05522cf5ce..299a95c8e9e3 100644 --- a/core/java/android/provider/Browser.java +++ b/core/java/android/provider/Browser.java @@ -244,6 +244,7 @@ public static final void sendString(Context c, */ public static final Cursor getAllBookmarks(ContentResolver cr) throws IllegalStateException { + android.util.SeempLog.record(32); return new MatrixCursor(new String[]{Bookmarks.URL}, 0); } @@ -256,6 +257,7 @@ public static final Cursor getAllBookmarks(ContentResolver cr) throws */ public static final Cursor getAllVisitedUrls(ContentResolver cr) throws IllegalStateException { + android.util.SeempLog.record(33); return new MatrixCursor(new String[]{Combined.URL}, 0); } @@ -264,6 +266,7 @@ private static final void addOrUrlEquals(StringBuilder sb) { } private static final Cursor getVisitedLike(ContentResolver cr, String url) { + android.util.SeempLog.record(34); boolean secure = false; String compareString = url; if (compareString.startsWith("http://")) { @@ -324,6 +327,7 @@ public static final void updateVisitedHistory(ContentResolver cr, */ @Deprecated public static final String[] getVisitedHistory(ContentResolver cr) { + android.util.SeempLog.record(35); return new String[0]; } @@ -359,6 +363,7 @@ public static final boolean canClearHistory(ContentResolver cr) { * @removed */ public static final void clearHistory(ContentResolver cr) { + android.util.SeempLog.record(37); } @@ -420,6 +425,7 @@ public static final void clearSearches(ContentResolver cr) { */ public static final void requestAllIcons(ContentResolver cr, String where, WebIconDatabase.IconListener listener) { + android.util.SeempLog.record(36); // Do nothing: this is no longer used. } diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index d9ce57af8c01..8cb0bb897802 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -871,6 +871,7 @@ private Attendees() {} * @return A Cursor containing all attendees for the event */ public static final Cursor query(ContentResolver cr, long eventId, String[] projection) { + android.util.SeempLog.record(54); String[] attArgs = {Long.toString(eventId)}; return cr.query(CONTENT_URI, projection, ATTENDEES_WHERE, attArgs /* selection args */, null /* sort order */); @@ -1750,6 +1751,7 @@ private Instances() {} */ public static final Cursor query(ContentResolver cr, String[] projection, long begin, long end) { + android.util.SeempLog.record(54); Uri.Builder builder = CONTENT_URI.buildUpon(); ContentUris.appendId(builder, begin); ContentUris.appendId(builder, end); @@ -1779,6 +1781,7 @@ public static final Cursor query(ContentResolver cr, String[] projection, */ public static final Cursor query(ContentResolver cr, String[] projection, long begin, long end, String searchQuery) { + android.util.SeempLog.record(54); Uri.Builder builder = CONTENT_SEARCH_URI.buildUpon(); ContentUris.appendId(builder, begin); ContentUris.appendId(builder, end); @@ -2029,6 +2032,7 @@ private EventDays() {} */ public static final Cursor query(ContentResolver cr, int startDay, int numDays, String[] projection) { + android.util.SeempLog.record(54); if (numDays < 1) { return null; } @@ -2112,6 +2116,7 @@ private Reminders() {} * @return A Cursor containing all reminders for the event */ public static final Cursor query(ContentResolver cr, long eventId, String[] projection) { + android.util.SeempLog.record(54); String[] remArgs = {Long.toString(eventId)}; return cr.query(CONTENT_URI, projection, REMINDERS_WHERE, remArgs /*selection args*/, null /* sort order */); @@ -2262,6 +2267,7 @@ private CalendarAlerts() {} */ public static final Uri insert(ContentResolver cr, long eventId, long begin, long end, long alarmTime, int minutes) { + android.util.SeempLog.record(51); ContentValues values = new ContentValues(); values.put(CalendarAlerts.EVENT_ID, eventId); values.put(CalendarAlerts.BEGIN, begin); @@ -2289,6 +2295,7 @@ public static final Uri insert(ContentResolver cr, long eventId, * @hide */ public static final long findNextAlarmTime(ContentResolver cr, long millis) { + android.util.SeempLog.record(53); String selection = ALARM_TIME + ">=" + millis; // TODO: construct an explicit SQL query so that we can add // "LIMIT 1" to the end and get just one result. @@ -2413,6 +2420,7 @@ public static void scheduleAlarm(Context context, AlarmManager manager, long ala */ public static final boolean alarmExists(ContentResolver cr, long eventId, long begin, long alarmTime) { + android.util.SeempLog.record(52); // TODO: construct an explicit SQL query so that we can add // "LIMIT 1" to the end and get just one result. String[] projection = new String[] { ALARM_TIME }; diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 70de09ebe85f..91e156429a82 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -98,6 +98,13 @@ public static class Calls implements BaseColumns { */ public static final String LIMIT_PARAM_KEY = "limit"; + /** + * Form of {@link #CONTENT_URI} which limits the query results to a single result. + */ + private static final Uri CONTENT_URI_LIMIT_1 = CONTENT_URI.buildUpon() + .appendQueryParameter(LIMIT_PARAM_KEY, "1") + .build(); + /** * Query parameter used to specify the starting record to return. *

@@ -842,11 +849,11 @@ public static String getLastOutgoingCall(Context context) { Cursor c = null; try { c = resolver.query( - CONTENT_URI, + CONTENT_URI_LIMIT_1, new String[] {NUMBER}, TYPE + " = " + OUTGOING_TYPE, null, - DEFAULT_SORT_ORDER + " LIMIT 1"); + DEFAULT_SORT_ORDER); if (c == null || !c.moveToFirst()) { return ""; } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 3f9871f8de0a..1f643cefcfa4 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1634,6 +1634,7 @@ private Contacts() {} * {@link #CONTENT_LOOKUP_URI} to attempt refreshing. */ public static Uri getLookupUri(ContentResolver resolver, Uri contactUri) { + android.util.SeempLog.record(86); final Cursor c = resolver.query(contactUri, new String[] { Contacts.LOOKUP_KEY, Contacts._ID }, null, null, null); @@ -1661,6 +1662,7 @@ public static Uri getLookupUri(ContentResolver resolver, Uri contactUri) { * provided parameters. */ public static Uri getLookupUri(long contactId, String lookupKey) { + android.util.SeempLog.record(86); if (TextUtils.isEmpty(lookupKey)) { return null; } @@ -1674,6 +1676,7 @@ public static Uri getLookupUri(long contactId, String lookupKey) { * Returns null if the contact cannot be found. */ public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) { + android.util.SeempLog.record(87); if (lookupUri == null) { return null; } @@ -2163,6 +2166,7 @@ private Photo() {} */ public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri, boolean preferHighres) { + android.util.SeempLog.record(88); if (preferHighres) { final Uri displayPhotoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.DISPLAY_PHOTO); @@ -2211,6 +2215,7 @@ public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri co * of the thumbnail the high-res picture is preferred */ public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri) { + android.util.SeempLog.record(88); return openContactPhotoInputStream(cr, contactUri, false); } } @@ -2908,6 +2913,7 @@ private RawContacts() { * entry of the given {@link RawContacts} entry. */ public static Uri getContactLookupUri(ContentResolver resolver, Uri rawContactUri) { + android.util.SeempLog.record(89); // TODO: use a lighter query by joining rawcontacts with contacts in provider final Uri dataUri = Uri.withAppendedPath(rawContactUri, Data.CONTENT_DIRECTORY); final Cursor cursor = resolver.query(dataUri, new String[] { @@ -4922,6 +4928,7 @@ private Data() {} *

*/ public static Uri getContactLookupUri(ContentResolver resolver, Uri dataUri) { + android.util.SeempLog.record(89); final Cursor cursor = resolver.query(dataUri, new String[] { RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY }, null, null, null); diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index 0e782d752815..b362c7a311d2 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -1144,6 +1144,7 @@ private Bundle callUnchecked(String method, String arg, Bundle extras) out.putParcelable(DocumentsContract.EXTRA_RESULT, path); } else if (METHOD_GET_DOCUMENT_METADATA.equals(method)) { + enforceReadPermissionInner(documentUri, getCallingPackage(), null); return getDocumentMetadata(documentId); } else { throw new UnsupportedOperationException("Method not supported " + method); diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index a2c5a92e52a2..062983a0cbfc 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -600,6 +600,11 @@ public static boolean isStatusCompleted(int status) { */ public static final int STATUS_QUEUED_FOR_WIFI = 196; + /** + * This download is paused manually. + */ + public static final int STATUS_PAUSED_MANUAL = 197; + /** * This download couldn't be completed due to insufficient storage * space. Typically, this is because the SD card is full. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 501d7f1d97c9..85c64853f484 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -897,6 +897,19 @@ public final class Settings { public static final String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = "android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS"; + /** + * @hide + * Activity Action: Show the "app ops" details screen. + *

+ * Input: The Intent's data URI specifies the application package name + * to be shown, with the "package" scheme. That is "package:com.my.app". + *

+ * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_APP_OPS_DETAILS_SETTINGS = + "android.settings.APP_OPS_DETAILS_SETTINGS"; + /** * @hide * Activity Action: Show the "app ops" settings screen. @@ -2377,6 +2390,7 @@ public static String getString(ContentResolver resolver, String name) { /** @hide */ public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { + android.util.SeempLog.record(android.util.SeempLog.getSeempGetApiIdFromValue(name)); if (MOVED_TO_SECURE.contains(name)) { Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System" + " to android.provider.Settings.Secure, returning read-only value."); @@ -2404,6 +2418,7 @@ public static boolean putString(ContentResolver resolver, String name, String va /** @hide */ public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userHandle) { + android.util.SeempLog.record(android.util.SeempLog.getSeempPutApiIdFromValue(name)); if (MOVED_TO_SECURE.contains(name)) { Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System" + " to android.provider.Settings.Secure, value is unchanged."); @@ -2499,6 +2514,32 @@ public static int getIntForUser(ContentResolver cr, String name, int userHandle) } } + /** + * @hide + * Convenience function for retrieving a single system settings value + * as a boolean. Note that internally setting values are always + * stored as strings; this function converts the string to a boolean + * for you. It will only return true if the stored value is "1" + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * @param def Value to return if the setting is not defined. + * + * @return The setting's current value, or 'def' if it is not defined + * or not a valid integer. + */ + public static boolean getBoolean(ContentResolver cr, String name, boolean def) { + String v = getString(cr, name); + try { + if(v != null) + return "1".equals(v); + else + return def; + } catch (NumberFormatException e) { + return def; + } + } + /** * Convenience function for updating a single settings value as an * integer. This will either create a new entry in the table if the @@ -2522,6 +2563,24 @@ public static boolean putIntForUser(ContentResolver cr, String name, int value, return putStringForUser(cr, name, Integer.toString(value), userHandle); } + /** + * @hide + * Convenience function for updating a single settings value as a + * boolean. This will either create a new entry in the table if the + * given name does not exist, or modify the value of the existing row + * with that name. Note that internally setting values are always + * stored as strings, so this function converts the given value to a + * string (1 or 0) before storing it. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to modify. + * @param value The new value for the setting. + * @return true if the value was set, false on database errors + */ + public static boolean putBoolean(ContentResolver cr, String name, boolean value) { + return putString(cr, name, value ? "1" : "0"); + } + /** * Convenience function for retrieving a single system settings value * as a {@code long}. Note that internally setting values are always @@ -3113,16 +3172,8 @@ public boolean validate(String value) { */ public static final String FONT_SCALE = "font_scale"; - private static final Validator FONT_SCALE_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - try { - return Float.parseFloat(value) >= 0; - } catch (NumberFormatException | NullPointerException e) { - return false; - } - } - }; + private static final Validator FONT_SCALE_VALIDATOR = + new SettingsValidators.InclusiveFloatRangeValidator(0.85f, 1.3f); /** * The serialized system locale value. @@ -3490,6 +3541,14 @@ public boolean validate(@Nullable String value) { */ public static final String RINGTONE = "ringtone"; + /** + * Persistent store for the system-wide default ringtone for Slot2 URI. + * + * @see #RINGTONE + * @see #DEFAULT_RINGTONE2_URI + */ + public static final String RINGTONE2 = "ringtone2"; + private static final Validator RINGTONE_VALIDATOR = URI_VALIDATOR; /** @@ -3502,11 +3561,24 @@ public boolean validate(@Nullable String value) { */ public static final Uri DEFAULT_RINGTONE_URI = getUriFor(RINGTONE); + /** + * A {@link Uri} that will point to the current default ringtone for Slot2 + * at any given time. + * + * @see #DEFAULT_RINGTONE_URI + */ + public static final Uri DEFAULT_RINGTONE2_URI = getUriFor(RINGTONE2); + /** {@hide} */ public static final String RINGTONE_CACHE = "ringtone_cache"; /** {@hide} */ public static final Uri RINGTONE_CACHE_URI = getUriFor(RINGTONE_CACHE); + /** {@hide} */ + public static final String RINGTONE2_CACHE = "ringtone2_cache"; + /** {@hide} */ + public static final Uri RINGTONE2_CACHE_URI = getUriFor(RINGTONE2_CACHE); + /** * Persistent store for the system-wide default notification sound. * @@ -3837,6 +3909,30 @@ public boolean validate(@Nullable String value) { /** @hide */ public static final Validator SHOW_WEB_SUGGESTIONS_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Whether to enable Smart Pixels + * @hide + */ + public static final String SMART_PIXELS_ENABLE = "smart_pixels_enable"; + + /** + * Smart Pixels pattern + * @hide + */ + public static final String SMART_PIXELS_PATTERN = "smart_pixels_pattern"; + + /** + * Smart Pixels Shift Timeout + * @hide + */ + public static final String SMART_PIXELS_SHIFT_TIMEOUT = "smart_pixels_shift_timeout"; + + /** + * Whether Smart Pixels should enable on power saver mode + * @hide + */ + public static final String SMART_PIXELS_ON_POWER_SAVE = "smart_pixels_on_power_save"; + /** * Whether the notification LED should repeatedly flash when a notification is * pending. The value is boolean (1 or 0). @@ -4079,13 +4175,47 @@ public boolean validate(@Nullable String value) { /** * Setting to determine whether or not to show the battery percentage in the status bar. * 0 - Don't show percentage - * 1 - Show percentage + * 1 - Show percentage outside + * 2 - Show percentage inside * @hide */ public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent"; /** @hide */ - private static final Validator SHOW_BATTERY_PERCENT_VALIDATOR = BOOLEAN_VALIDATOR; + public static final Validator SHOW_BATTERY_PERCENT_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); + + /** + * Custom button brightness value for manual mode + * + * @hide + */ + public static final String CUSTOM_BUTTON_BRIGHTNESS = "custom_button_brightness"; + + /** + * use same value for buttons as for screen (manual and auto mode) + * + * @hide + */ + public static final String CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS = "custom_button_use_screen_brightness"; + + /** + * disable all button brightness (manual and auto mode) + * + * @hide + */ + public static final String BUTTON_BACKLIGHT_ENABLE = "button_backlight_enable"; + + /** + * Timeout value for button lights. 0 = disabled + * @hide + */ + public static final String BUTTON_BACKLIGHT_TIMEOUT = "button_backlight_timeout"; + + /** + * @hide + */ + public static final String BUTTON_BACKLIGHT_ON_TOUCH_ONLY = "button_backlight_on_touch_only"; /** * IMPORTANT: If you add a new public settings you also have to add it to @@ -4095,860 +4225,2243 @@ public boolean validate(@Nullable String value) { */ /** - * Settings to backup. This is here so that it's in the same place as the settings - * keys and easy to update. - * - * NOTE: Settings are backed up and restored in the order they appear - * in this array. If you have one setting depending on another, - * make sure that they are ordered appropriately. - * + * show clear all recents button * @hide */ - public static final String[] SETTINGS_TO_BACKUP = { - STAY_ON_WHILE_PLUGGED_IN, // moved to global - WIFI_USE_STATIC_IP, - WIFI_STATIC_IP, - WIFI_STATIC_GATEWAY, - WIFI_STATIC_NETMASK, - WIFI_STATIC_DNS1, - WIFI_STATIC_DNS2, - BLUETOOTH_DISCOVERABILITY, - BLUETOOTH_DISCOVERABILITY_TIMEOUT, - FONT_SCALE, - DIM_SCREEN, - SCREEN_OFF_TIMEOUT, - SCREEN_BRIGHTNESS_MODE, - SCREEN_AUTO_BRIGHTNESS_ADJ, - SCREEN_BRIGHTNESS_FOR_VR, - VIBRATE_INPUT_DEVICES, - MODE_RINGER_STREAMS_AFFECTED, - TEXT_AUTO_REPLACE, - TEXT_AUTO_CAPS, - TEXT_AUTO_PUNCTUATE, - TEXT_SHOW_PASSWORD, - AUTO_TIME, // moved to global - AUTO_TIME_ZONE, // moved to global - TIME_12_24, - DATE_FORMAT, - DTMF_TONE_WHEN_DIALING, - DTMF_TONE_TYPE_WHEN_DIALING, - HEARING_AID, - TTY_MODE, - MASTER_MONO, - SOUND_EFFECTS_ENABLED, - HAPTIC_FEEDBACK_ENABLED, - POWER_SOUNDS_ENABLED, // moved to global - DOCK_SOUNDS_ENABLED, // moved to global - LOCKSCREEN_SOUNDS_ENABLED, - SHOW_WEB_SUGGESTIONS, - SIP_CALL_OPTIONS, - SIP_RECEIVE_CALLS, - POINTER_SPEED, - VIBRATE_WHEN_RINGING, - RINGTONE, - LOCK_TO_APP_ENABLED, - NOTIFICATION_SOUND, - ACCELEROMETER_ROTATION, - SHOW_BATTERY_PERCENT, - NOTIFICATION_VIBRATION_INTENSITY, - HAPTIC_FEEDBACK_INTENSITY, - DISPLAY_COLOR_MODE, - NOTIFICATION_LIGHT_PULSE, - }; + public static final String SHOW_CLEAR_ALL_RECENTS = "show_clear_all_recents"; + /** @hide */ + private static final Validator SHOW_CLEAR_ALL_RECENTS_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * location of the clear all rectents button + * @hide + */ + public static final String RECENTS_CLEAR_ALL_LOCATION = "recents_clear_all_location"; + /** @hide */ + private static final Validator RECENTS_CLEAR_ALL_LOCATION_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * Keys we no longer back up under the current schema, but want to continue to - * process when restoring historical backup datasets. - * - * All settings in {@link LEGACY_RESTORE_SETTINGS} array *must* have a non-null validator, - * otherwise they won't be restored. + * @hide + */ + public static final String QS_LAYOUT_COLUMNS = "qs_layout_columns"; + /** @hide */ + private static final Validator QS_LAYOUT_COLUMNS_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Number of qs columns on landscape orientation + * @hide + */ + public static final String QS_LAYOUT_COLUMNS_LANDSCAPE = "qs_layout_columns_landscape"; + /** @hide */ + private static final Validator QS_LAYOUT_COLUMNS_LANDSCAPE_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * @hide + */ + public static final String QS_LAYOUT_ROWS = "qs_layout_rows"; + + /** @hide */ + private static final Validator QS_LAYOUT_ROWS_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * @hide + */ + public static final String QS_LAYOUT_ROWS_LANDSCAPE = "qs_layout_rows_landscape"; + /** @hide */ + private static final Validator QS_LAYOUT_ROWS_LANDSCAPE_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Whether to display qs tile titles in the qs panel + * @hide + */ + public static final String QS_TILE_HIDE_TITLE = "qs_tile_hide_title"; + /** @hide */ + private static final Validator QS_TILE_HIDE_TITLE_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether to display the reboot option in the power menu * * @hide */ - public static final String[] LEGACY_RESTORE_SETTINGS = { - }; + public static final String POWERMENU_REBOOT = "powermenu_reboot"; + /** @hide */ + private static final Validator POWERMENU_REBOOT_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * These are all public system settings + * Whether to display the advanced reboot option in the power menu * * @hide */ - public static final Set PUBLIC_SETTINGS = new ArraySet<>(); - static { - PUBLIC_SETTINGS.add(END_BUTTON_BEHAVIOR); - PUBLIC_SETTINGS.add(WIFI_USE_STATIC_IP); - PUBLIC_SETTINGS.add(WIFI_STATIC_IP); - PUBLIC_SETTINGS.add(WIFI_STATIC_GATEWAY); - PUBLIC_SETTINGS.add(WIFI_STATIC_NETMASK); - PUBLIC_SETTINGS.add(WIFI_STATIC_DNS1); - PUBLIC_SETTINGS.add(WIFI_STATIC_DNS2); - PUBLIC_SETTINGS.add(BLUETOOTH_DISCOVERABILITY); - PUBLIC_SETTINGS.add(BLUETOOTH_DISCOVERABILITY_TIMEOUT); - PUBLIC_SETTINGS.add(NEXT_ALARM_FORMATTED); - PUBLIC_SETTINGS.add(FONT_SCALE); - PUBLIC_SETTINGS.add(DIM_SCREEN); - PUBLIC_SETTINGS.add(SCREEN_OFF_TIMEOUT); - PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS); - PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_FOR_VR); - PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_MODE); - PUBLIC_SETTINGS.add(MODE_RINGER_STREAMS_AFFECTED); - PUBLIC_SETTINGS.add(MUTE_STREAMS_AFFECTED); - PUBLIC_SETTINGS.add(VIBRATE_ON); - PUBLIC_SETTINGS.add(VOLUME_RING); - PUBLIC_SETTINGS.add(VOLUME_SYSTEM); - PUBLIC_SETTINGS.add(VOLUME_VOICE); - PUBLIC_SETTINGS.add(VOLUME_MUSIC); - PUBLIC_SETTINGS.add(VOLUME_ALARM); - PUBLIC_SETTINGS.add(VOLUME_NOTIFICATION); - PUBLIC_SETTINGS.add(VOLUME_BLUETOOTH_SCO); - PUBLIC_SETTINGS.add(RINGTONE); - PUBLIC_SETTINGS.add(NOTIFICATION_SOUND); - PUBLIC_SETTINGS.add(ALARM_ALERT); - PUBLIC_SETTINGS.add(TEXT_AUTO_REPLACE); - PUBLIC_SETTINGS.add(TEXT_AUTO_CAPS); - PUBLIC_SETTINGS.add(TEXT_AUTO_PUNCTUATE); - PUBLIC_SETTINGS.add(TEXT_SHOW_PASSWORD); - PUBLIC_SETTINGS.add(SHOW_GTALK_SERVICE_STATUS); - PUBLIC_SETTINGS.add(WALLPAPER_ACTIVITY); - PUBLIC_SETTINGS.add(TIME_12_24); - PUBLIC_SETTINGS.add(DATE_FORMAT); - PUBLIC_SETTINGS.add(SETUP_WIZARD_HAS_RUN); - PUBLIC_SETTINGS.add(ACCELEROMETER_ROTATION); - PUBLIC_SETTINGS.add(USER_ROTATION); - PUBLIC_SETTINGS.add(DTMF_TONE_WHEN_DIALING); - PUBLIC_SETTINGS.add(SOUND_EFFECTS_ENABLED); - PUBLIC_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED); - PUBLIC_SETTINGS.add(SHOW_WEB_SUGGESTIONS); - PUBLIC_SETTINGS.add(VIBRATE_WHEN_RINGING); - } + public static final String POWERMENU_ADVANCED_REBOOT = "powermenu_advanced_reboot"; + /** @hide */ + private static final Validator POWERMENU_ADVANCED_REBOOT_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * These are all hidden system settings. + * Whether to display the screenshot option in the power menu * * @hide */ - public static final Set PRIVATE_SETTINGS = new ArraySet<>(); - static { - PRIVATE_SETTINGS.add(WIFI_USE_STATIC_IP); - PRIVATE_SETTINGS.add(END_BUTTON_BEHAVIOR); - PRIVATE_SETTINGS.add(ADVANCED_SETTINGS); - PRIVATE_SETTINGS.add(SCREEN_AUTO_BRIGHTNESS_ADJ); - PRIVATE_SETTINGS.add(VIBRATE_INPUT_DEVICES); - PRIVATE_SETTINGS.add(VOLUME_MASTER); - PRIVATE_SETTINGS.add(MASTER_MONO); - PRIVATE_SETTINGS.add(NOTIFICATIONS_USE_RING_VOLUME); - PRIVATE_SETTINGS.add(VIBRATE_IN_SILENT); - PRIVATE_SETTINGS.add(MEDIA_BUTTON_RECEIVER); - PRIVATE_SETTINGS.add(HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY); - PRIVATE_SETTINGS.add(DTMF_TONE_TYPE_WHEN_DIALING); - PRIVATE_SETTINGS.add(HEARING_AID); - PRIVATE_SETTINGS.add(TTY_MODE); - PRIVATE_SETTINGS.add(NOTIFICATION_LIGHT_PULSE); - PRIVATE_SETTINGS.add(POINTER_LOCATION); - PRIVATE_SETTINGS.add(SHOW_TOUCHES); - PRIVATE_SETTINGS.add(WINDOW_ORIENTATION_LISTENER_LOG); - PRIVATE_SETTINGS.add(POWER_SOUNDS_ENABLED); - PRIVATE_SETTINGS.add(DOCK_SOUNDS_ENABLED); - PRIVATE_SETTINGS.add(LOCKSCREEN_SOUNDS_ENABLED); - PRIVATE_SETTINGS.add(LOCKSCREEN_DISABLED); - PRIVATE_SETTINGS.add(LOW_BATTERY_SOUND); - PRIVATE_SETTINGS.add(DESK_DOCK_SOUND); - PRIVATE_SETTINGS.add(DESK_UNDOCK_SOUND); - PRIVATE_SETTINGS.add(CAR_DOCK_SOUND); - PRIVATE_SETTINGS.add(CAR_UNDOCK_SOUND); - PRIVATE_SETTINGS.add(LOCK_SOUND); - PRIVATE_SETTINGS.add(UNLOCK_SOUND); - PRIVATE_SETTINGS.add(SIP_RECEIVE_CALLS); - PRIVATE_SETTINGS.add(SIP_CALL_OPTIONS); - PRIVATE_SETTINGS.add(SIP_ALWAYS); - PRIVATE_SETTINGS.add(SIP_ADDRESS_ONLY); - PRIVATE_SETTINGS.add(SIP_ASK_ME_EACH_TIME); - PRIVATE_SETTINGS.add(POINTER_SPEED); - PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED); - PRIVATE_SETTINGS.add(EGG_MODE); - PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT); - PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE); - } + public static final String POWERMENU_SCREENSHOT = "powermenu_screenshot"; + /** @hide */ + private static final Validator POWERMENU_SCREENSHOT_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * These are all public system settings - * - * All settings in {@link SETTINGS_TO_BACKUP} array *must* have a non-null validator, - * otherwise they won't be restored. + * Whether to display the airplane option in the power menu * * @hide */ - public static final Map VALIDATORS = new ArrayMap<>(); - static { - VALIDATORS.put(STAY_ON_WHILE_PLUGGED_IN, STAY_ON_WHILE_PLUGGED_IN_VALIDATOR); - VALIDATORS.put(END_BUTTON_BEHAVIOR, END_BUTTON_BEHAVIOR_VALIDATOR); - VALIDATORS.put(WIFI_USE_STATIC_IP, WIFI_USE_STATIC_IP_VALIDATOR); - VALIDATORS.put(BLUETOOTH_DISCOVERABILITY, BLUETOOTH_DISCOVERABILITY_VALIDATOR); - VALIDATORS.put(BLUETOOTH_DISCOVERABILITY_TIMEOUT, - BLUETOOTH_DISCOVERABILITY_TIMEOUT_VALIDATOR); - VALIDATORS.put(NEXT_ALARM_FORMATTED, NEXT_ALARM_FORMATTED_VALIDATOR); - VALIDATORS.put(FONT_SCALE, FONT_SCALE_VALIDATOR); - VALIDATORS.put(DIM_SCREEN, DIM_SCREEN_VALIDATOR); - VALIDATORS.put(DISPLAY_COLOR_MODE, DISPLAY_COLOR_MODE_VALIDATOR); - VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR); - VALIDATORS.put(SCREEN_BRIGHTNESS_FOR_VR, SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR); - VALIDATORS.put(SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_VALIDATOR); - VALIDATORS.put(MODE_RINGER_STREAMS_AFFECTED, MODE_RINGER_STREAMS_AFFECTED_VALIDATOR); - VALIDATORS.put(MUTE_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED_VALIDATOR); - VALIDATORS.put(VIBRATE_ON, VIBRATE_ON_VALIDATOR); - VALIDATORS.put(NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); - VALIDATORS.put(HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); - VALIDATORS.put(RINGTONE, RINGTONE_VALIDATOR); - VALIDATORS.put(NOTIFICATION_SOUND, NOTIFICATION_SOUND_VALIDATOR); - VALIDATORS.put(ALARM_ALERT, ALARM_ALERT_VALIDATOR); - VALIDATORS.put(TEXT_AUTO_REPLACE, TEXT_AUTO_REPLACE_VALIDATOR); - VALIDATORS.put(TEXT_AUTO_CAPS, TEXT_AUTO_CAPS_VALIDATOR); - VALIDATORS.put(TEXT_AUTO_PUNCTUATE, TEXT_AUTO_PUNCTUATE_VALIDATOR); - VALIDATORS.put(TEXT_SHOW_PASSWORD, TEXT_SHOW_PASSWORD_VALIDATOR); - VALIDATORS.put(AUTO_TIME, AUTO_TIME_VALIDATOR); - VALIDATORS.put(AUTO_TIME_ZONE, AUTO_TIME_ZONE_VALIDATOR); - VALIDATORS.put(SHOW_GTALK_SERVICE_STATUS, SHOW_GTALK_SERVICE_STATUS_VALIDATOR); - VALIDATORS.put(WALLPAPER_ACTIVITY, WALLPAPER_ACTIVITY_VALIDATOR); - VALIDATORS.put(TIME_12_24, TIME_12_24_VALIDATOR); - VALIDATORS.put(DATE_FORMAT, DATE_FORMAT_VALIDATOR); - VALIDATORS.put(SETUP_WIZARD_HAS_RUN, SETUP_WIZARD_HAS_RUN_VALIDATOR); - VALIDATORS.put(ACCELEROMETER_ROTATION, ACCELEROMETER_ROTATION_VALIDATOR); - VALIDATORS.put(USER_ROTATION, USER_ROTATION_VALIDATOR); - VALIDATORS.put(DTMF_TONE_WHEN_DIALING, DTMF_TONE_WHEN_DIALING_VALIDATOR); - VALIDATORS.put(SOUND_EFFECTS_ENABLED, SOUND_EFFECTS_ENABLED_VALIDATOR); - VALIDATORS.put(HAPTIC_FEEDBACK_ENABLED, HAPTIC_FEEDBACK_ENABLED_VALIDATOR); - VALIDATORS.put(POWER_SOUNDS_ENABLED, POWER_SOUNDS_ENABLED_VALIDATOR); - VALIDATORS.put(DOCK_SOUNDS_ENABLED, DOCK_SOUNDS_ENABLED_VALIDATOR); - VALIDATORS.put(SHOW_WEB_SUGGESTIONS, SHOW_WEB_SUGGESTIONS_VALIDATOR); - VALIDATORS.put(WIFI_USE_STATIC_IP, WIFI_USE_STATIC_IP_VALIDATOR); - VALIDATORS.put(END_BUTTON_BEHAVIOR, END_BUTTON_BEHAVIOR_VALIDATOR); - VALIDATORS.put(ADVANCED_SETTINGS, ADVANCED_SETTINGS_VALIDATOR); - VALIDATORS.put(SCREEN_AUTO_BRIGHTNESS_ADJ, SCREEN_AUTO_BRIGHTNESS_ADJ_VALIDATOR); - VALIDATORS.put(VIBRATE_INPUT_DEVICES, VIBRATE_INPUT_DEVICES_VALIDATOR); - VALIDATORS.put(MASTER_MONO, MASTER_MONO_VALIDATOR); - VALIDATORS.put(NOTIFICATIONS_USE_RING_VOLUME, NOTIFICATIONS_USE_RING_VOLUME_VALIDATOR); - VALIDATORS.put(VIBRATE_IN_SILENT, VIBRATE_IN_SILENT_VALIDATOR); - VALIDATORS.put(MEDIA_BUTTON_RECEIVER, MEDIA_BUTTON_RECEIVER_VALIDATOR); - VALIDATORS.put(HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, - HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY_VALIDATOR); - VALIDATORS.put(VIBRATE_WHEN_RINGING, VIBRATE_WHEN_RINGING_VALIDATOR); - VALIDATORS.put(DTMF_TONE_TYPE_WHEN_DIALING, DTMF_TONE_TYPE_WHEN_DIALING_VALIDATOR); - VALIDATORS.put(HEARING_AID, HEARING_AID_VALIDATOR); - VALIDATORS.put(TTY_MODE, TTY_MODE_VALIDATOR); - VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, NOTIFICATION_LIGHT_PULSE_VALIDATOR); - VALIDATORS.put(POINTER_LOCATION, POINTER_LOCATION_VALIDATOR); - VALIDATORS.put(SHOW_TOUCHES, SHOW_TOUCHES_VALIDATOR); - VALIDATORS.put(WINDOW_ORIENTATION_LISTENER_LOG, - WINDOW_ORIENTATION_LISTENER_LOG_VALIDATOR); - VALIDATORS.put(LOCKSCREEN_SOUNDS_ENABLED, LOCKSCREEN_SOUNDS_ENABLED_VALIDATOR); - VALIDATORS.put(LOCKSCREEN_DISABLED, LOCKSCREEN_DISABLED_VALIDATOR); - VALIDATORS.put(SIP_RECEIVE_CALLS, SIP_RECEIVE_CALLS_VALIDATOR); - VALIDATORS.put(SIP_CALL_OPTIONS, SIP_CALL_OPTIONS_VALIDATOR); - VALIDATORS.put(SIP_ALWAYS, SIP_ALWAYS_VALIDATOR); - VALIDATORS.put(SIP_ADDRESS_ONLY, SIP_ADDRESS_ONLY_VALIDATOR); - VALIDATORS.put(SIP_ASK_ME_EACH_TIME, SIP_ASK_ME_EACH_TIME_VALIDATOR); - VALIDATORS.put(POINTER_SPEED, POINTER_SPEED_VALIDATOR); - VALIDATORS.put(LOCK_TO_APP_ENABLED, LOCK_TO_APP_ENABLED_VALIDATOR); - VALIDATORS.put(EGG_MODE, EGG_MODE_VALIDATOR); - VALIDATORS.put(WIFI_STATIC_IP, WIFI_STATIC_IP_VALIDATOR); - VALIDATORS.put(WIFI_STATIC_GATEWAY, WIFI_STATIC_GATEWAY_VALIDATOR); - VALIDATORS.put(WIFI_STATIC_NETMASK, WIFI_STATIC_NETMASK_VALIDATOR); - VALIDATORS.put(WIFI_STATIC_DNS1, WIFI_STATIC_DNS1_VALIDATOR); - VALIDATORS.put(WIFI_STATIC_DNS2, WIFI_STATIC_DNS2_VALIDATOR); - VALIDATORS.put(SHOW_BATTERY_PERCENT, SHOW_BATTERY_PERCENT_VALIDATOR); - VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR); - } + public static final String POWERMENU_AIRPLANE = "powermenu_airplane"; + /** @hide */ + private static final Validator POWERMENU_AIRPLANE_VALIDATOR = + BOOLEAN_VALIDATOR; - /** - * These entries are considered common between the personal and the managed profile, - * since the managed profile doesn't get to change them. + /** + * Show or hide clock + * 0 - hide + * 1 - show (default) + * @hide */ - private static final Set CLONE_TO_MANAGED_PROFILE = new ArraySet<>(); - static { - CLONE_TO_MANAGED_PROFILE.add(DATE_FORMAT); - CLONE_TO_MANAGED_PROFILE.add(HAPTIC_FEEDBACK_ENABLED); - CLONE_TO_MANAGED_PROFILE.add(SOUND_EFFECTS_ENABLED); - CLONE_TO_MANAGED_PROFILE.add(TEXT_SHOW_PASSWORD); - CLONE_TO_MANAGED_PROFILE.add(TIME_12_24); - } - + public static final String STATUS_BAR_CLOCK = "status_bar_clock"; /** @hide */ - public static void getCloneToManagedProfileSettings(Set outKeySet) { - outKeySet.addAll(CLONE_TO_MANAGED_PROFILE); - } + public static final Validator STATUS_BAR_CLOCK_VALIDATOR = BOOLEAN_VALIDATOR; /** - * These entries should be cloned from this profile's parent only if the dependency's - * value is true ("1") - * - * Note: the dependencies must be Secure settings - * + * Style of clock + * 0 - Left Clock (default) + * 1 - Center Clock + * 2 - Right Clock * @hide */ - public static final Map CLONE_FROM_PARENT_ON_VALUE = new ArrayMap<>(); - static { - CLONE_FROM_PARENT_ON_VALUE.put(RINGTONE, Secure.SYNC_PARENT_SOUNDS); - CLONE_FROM_PARENT_ON_VALUE.put(NOTIFICATION_SOUND, Secure.SYNC_PARENT_SOUNDS); - CLONE_FROM_PARENT_ON_VALUE.put(ALARM_ALERT, Secure.SYNC_PARENT_SOUNDS); - } - + public static final String STATUSBAR_CLOCK_STYLE = "statusbar_clock_style"; /** @hide */ - public static void getCloneFromParentOnValueSettings(Map outMap) { - outMap.putAll(CLONE_FROM_PARENT_ON_VALUE); - } + public static final Validator STATUSBAR_CLOCK_STYLE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); /** - * System settings which can be accessed by instant apps. + * Whether to show seconds next to clock in status bar + * 0 - hide (default) + * 1 - show * @hide */ - public static final Set INSTANT_APP_SETTINGS = new ArraySet<>(); - static { - INSTANT_APP_SETTINGS.add(TEXT_AUTO_REPLACE); - INSTANT_APP_SETTINGS.add(TEXT_AUTO_CAPS); - INSTANT_APP_SETTINGS.add(TEXT_AUTO_PUNCTUATE); - INSTANT_APP_SETTINGS.add(TEXT_SHOW_PASSWORD); - INSTANT_APP_SETTINGS.add(DATE_FORMAT); - INSTANT_APP_SETTINGS.add(FONT_SCALE); - INSTANT_APP_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED); - INSTANT_APP_SETTINGS.add(TIME_12_24); - INSTANT_APP_SETTINGS.add(SOUND_EFFECTS_ENABLED); - INSTANT_APP_SETTINGS.add(ACCELEROMETER_ROTATION); - } + public static final String STATUS_BAR_CLOCK_SECONDS = "status_bar_clock_seconds"; + /** @hide */ + public static final Validator STATUS_BAR_CLOCK_SECONDS_VALIDATOR = BOOLEAN_VALIDATOR; /** - * When to use Wi-Fi calling - * - * @see android.telephony.TelephonyManager.WifiCallingChoices + * AM/PM Style for clock options + * 0 - Normal AM/PM + * 1 - Small AM/PM + * 2 - No AM/PM (default) * @hide */ - public static final String WHEN_TO_MAKE_WIFI_CALLS = "when_to_make_wifi_calls"; - - // Settings moved to Settings.Secure + public static final String STATUSBAR_CLOCK_AM_PM_STYLE = "statusbar_clock_am_pm_style"; + /** @hide */ + public static final Validator STATUSBAR_CLOCK_AM_PM_STYLE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); /** - * @deprecated Use {@link android.provider.Settings.Global#ADB_ENABLED} - * instead + * Shows custom date before clock time + * 0 - No Date + * 1 - Small Date + * 2 - Normal Date + * @hide */ - @Deprecated - public static final String ADB_ENABLED = Global.ADB_ENABLED; + public static final String STATUSBAR_CLOCK_DATE_DISPLAY = "statusbar_clock_date_display"; + /** @hide */ + public static final Validator STATUSBAR_CLOCK_DATE_DISPLAY_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); /** - * @deprecated Use {@link android.provider.Settings.Secure#ANDROID_ID} instead + * Whether the battery light should be enabled (if hardware supports it) + * The value is boolean (1 or 0). + * @hide */ - @Deprecated - public static final String ANDROID_ID = Secure.ANDROID_ID; + public static final String BATTERY_LIGHT_ENABLED = "battery_light_enabled"; + /** @hide */ + private static final Validator BATTERY_LIGHT_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#BLUETOOTH_ON} instead + * Whether to show battery light when DND mode is active + * @hide + */ + public static final String BATTERY_LIGHT_ALLOW_ON_DND = "battery_light_allow_on_dnd"; + /** @hide */ + private static final Validator BATTERY_LIGHT_ALLOW_ON_DND_VALIDATOR = + BOOLEAN_VALIDATOR; + /** + * Whether to show blinking light when battery is low + * @hide + */ + public static final String BATTERY_LIGHT_LOW_BLINKING = "battery_light_low_blinking"; + /** @hide */ + private static final Validator BATTERY_LIGHT_LOW_BLINKING_VALIDATOR = + BOOLEAN_VALIDATOR; + /** + * Low battery charging color + * @hide + */ + public static final String BATTERY_LIGHT_LOW_COLOR = "battery_light_low_color"; + /** @hide */ + private static final Validator BATTERY_LIGHT_LOW_COLOR_VALIDATOR = + ANY_STRING_VALIDATOR; + /** + * Medium battery charging color + * @hide + */ + public static final String BATTERY_LIGHT_MEDIUM_COLOR = "battery_light_medium_color"; + /** @hide */ + private static final Validator BATTERY_LIGHT_MEDIUM_COLOR_VALIDATOR = + ANY_STRING_VALIDATOR; + /** + * Full battery charging color + * @hide + */ + public static final String BATTERY_LIGHT_FULL_COLOR = "battery_light_full_color"; + /** @hide */ + private static final Validator BATTERY_LIGHT_FULL_COLOR_VALIDATOR = + ANY_STRING_VALIDATOR; + /** + * Really full 100 battery charging color + * @hide + */ + public static final String BATTERY_LIGHT_REALLYFULL_COLOR = "battery_light_reallyfull_color"; + /** @hide */ + private static final Validator BATTERY_LIGHT_REALLYFULL_COLOR_VALIDATOR = + ANY_STRING_VALIDATOR; + + /** + * @hide */ - @Deprecated - public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON; + public static final String BOTTOM_GESTURE_FEEDBACK_DURATION = "bottom_gesture_navigation_feedback_duration"; - private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + /** @hide */ + private static final Validator BOTTOM_GESTURE_FEEDBACK_DURATION_VALIDATOR = ANY_INTEGER_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead + * @hide */ - @Deprecated - public static final String DATA_ROAMING = Global.DATA_ROAMING; + public static final String BOTTOM_GESTURE_SWIPE_START = + "bottom_gesture_navigation_swipe_start"; + + private static final Validator BOTTOM_GESTURE_SWIPE_START_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead + * Whether to hide the lockscreen clock + * @hide */ - @Deprecated - public static final String DEVICE_PROVISIONED = Global.DEVICE_PROVISIONED; + public static final String LOCKSCREEN_CLOCK = "lockscreen_clock"; + /** @hide */ + private static final Validator LOCKSCREEN_CLOCK_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#HTTP_PROXY} instead + * Select which lockscreen clock style to display + * @hide */ - @Deprecated - public static final String HTTP_PROXY = Global.HTTP_PROXY; + public static final String LOCKSCREEN_CLOCK_SELECTION = "lockscreen_clock_selection"; + /** @hide */ + public static final Validator LOCKSCREEN_CLOCK_SELECTION_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 9); /** - * @deprecated Use {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS} instead + * Whether to hide the items underneath the lockscreen clock + * @hide */ - @Deprecated - public static final String INSTALL_NON_MARKET_APPS = Secure.INSTALL_NON_MARKET_APPS; + public static final String LOCKSCREEN_INFO = "lockscreen_info"; + /** @hide */ + private static final Validator LOCKSCREEN_INFO_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#LOCATION_PROVIDERS_ALLOWED} - * instead + * Sets the date string style + * 0 - Regular style + * 1 - Lowercase + * 2 - Uppercase + * @hide */ - @Deprecated - public static final String LOCATION_PROVIDERS_ALLOWED = Secure.LOCATION_PROVIDERS_ALLOWED; + public static final String STATUSBAR_CLOCK_DATE_STYLE = "statusbar_clock_date_style"; + /** @hide */ + public static final Validator STATUSBAR_CLOCK_DATE_STYLE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); + + /** + * Whether to show the negociated charger current in the lockscreen + * @hide + */ + public static final String LOCKSCREEN_CHARGING_CURRENT = "lockscreen_charging_current"; + /** @hide */ + private static final Validator LOCKSCREEN_CHARGING_CURRENT_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#LOGGING_ID} instead + * Stores the java DateFormat string for the date + * @hide */ - @Deprecated - public static final String LOGGING_ID = Secure.LOGGING_ID; + public static final String STATUSBAR_CLOCK_DATE_FORMAT = "statusbar_clock_date_format"; + /** @hide */ + public static final Validator STATUSBAR_CLOCK_DATE_FORMAT_VALIDATOR = ANY_STRING_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#NETWORK_PREFERENCE} instead + * Apps to skip for Pulse + * @hide */ - @Deprecated - public static final String NETWORK_PREFERENCE = Global.NETWORK_PREFERENCE; + public static final String PULSE_APPS_BLACKLIST = "pulse_apps_blacklist"; /** - * @deprecated Use {@link android.provider.Settings.Secure#PARENTAL_CONTROL_ENABLED} - * instead + * @hide */ - @Deprecated - public static final String PARENTAL_CONTROL_ENABLED = Secure.PARENTAL_CONTROL_ENABLED; + public static final String QS_QUICKBAR_COLUMNS = "qs_quickbar_columns"; + /** @hide */ + private static final Validator QS_QUICKBAR_COLUMNS_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#PARENTAL_CONTROL_LAST_UPDATE} - * instead + * Enable statusbar double tap gesture on to put device to sleep + * @hide */ - @Deprecated - public static final String PARENTAL_CONTROL_LAST_UPDATE = Secure.PARENTAL_CONTROL_LAST_UPDATE; + public static final String DOUBLE_TAP_SLEEP_GESTURE = "double_tap_sleep_gesture"; + /** @hide */ + private static final Validator DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#PARENTAL_CONTROL_REDIRECT_URL} - * instead + * Enable double tap gesture anywhere on the lock screen put device to sleep + * @hide */ - @Deprecated - public static final String PARENTAL_CONTROL_REDIRECT_URL = - Secure.PARENTAL_CONTROL_REDIRECT_URL; + public static final String DOUBLE_TAP_SLEEP_ANYWHERE = "double_tap_sleep_anywhere"; + /** @hide */ + private static final Validator DOUBLE_TAP_SLEEP_ANYWHERE_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#SETTINGS_CLASSNAME} instead + * Whether to show media art on lockscreen + * @hide */ - @Deprecated - public static final String SETTINGS_CLASSNAME = Secure.SETTINGS_CLASSNAME; + public static final String LOCKSCREEN_MEDIA_METADATA = "lockscreen_media_metadata"; + /** @hide */ + private static final Validator LOCKSCREEN_MEDIA_METADATA_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#USB_MASS_STORAGE_ENABLED} instead + * Wheter to show heads up only for dialer and sms apps + * @hide */ - @Deprecated - public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED; - - private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String LESS_BORING_HEADS_UP = "less_boring_heads_up"; /** - * @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead + * Whether to show VoLTE icon or not + * @hide */ - @Deprecated - public static final String USE_GOOGLE_MAIL = Global.USE_GOOGLE_MAIL; + public static final String SHOW_VOLTE_ICON = "volte_icon"; + /** @hide */ + private static final Validator SHOW_VOLTE_ICON_VALIDATOR = + BOOLEAN_VALIDATOR; - /** - * @deprecated Use - * {@link android.provider.Settings.Global#WIFI_MAX_DHCP_RETRY_COUNT} instead + /** + * Allow all rotations. + * @hide */ - @Deprecated - public static final String WIFI_MAX_DHCP_RETRY_COUNT = Global.WIFI_MAX_DHCP_RETRY_COUNT; + public static final String ACCELEROMETER_ROTATION_ANGLES = "accelerometer_rotation_angles"; + /** @hide */ + private static final Validator ACCELEROMETER_ROTATION_ANGLES_VALIDATOR = + ANY_STRING_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Global#WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS} instead + * Change volume up and down handlign based on rotation + * @hide */ - @Deprecated - public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = - Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS; + public static final String SWAP_VOLUME_BUTTONS = "swap_volume_buttons"; + /** @hide */ + private static final Validator SWAP_VOLUME_BUTTONS_VALIDATOR = + BOOLEAN_VALIDATOR; - /** - * @deprecated Use - * {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON} instead + /** + * Whether to enable the pixel navbar animation + * @hide */ - @Deprecated - public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = - Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; + public static final String PIXEL_NAV_ANIMATION = "pixel_nav_animation"; - private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = + /** + * Toast icon + * @hide + */ + public static final String TOAST_ICON = "toast_icon"; + /** @hide */ + private static final Validator TOAST_ICON_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} instead + * Select from various styles to use on the QS tiles + * + * @hide */ - @Deprecated - public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = - Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY; - - private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + public static final String QS_TILE_STYLE = "qs_tile_style"; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT} - * instead + * Show four g instead of LTE + * @hide */ - @Deprecated - public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = Global.WIFI_NUM_OPEN_NETWORKS_KEPT; + public static final String SHOW_FOURG = "show_fourg"; - private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + /** @hide */ + public static final Validator SHOW_FOURG_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * Whether to wake the screen with the home key, the value is boolean. + * @hide + */ + public static final String HOME_WAKE_SCREEN = "home_wake_screen"; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_ON} instead + * Volume rocker wake + * @hide */ - @Deprecated - public static final String WIFI_ON = Global.WIFI_ON; + public static final String VOLUME_ROCKER_WAKE = "volume_rocker_wake"; + /** @hide */ + private static final Validator VOLUME_ROCKER_WAKE_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE} - * instead + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = - Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE; + public static final String VOLUME_BUTTON_MUSIC_CONTROL = "volume_button_music_control"; + /** @hide */ + private static final Validator VOLUME_BUTTON_MUSIC_CONTROL_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_AP_COUNT} instead + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_AP_COUNT = Secure.WIFI_WATCHDOG_AP_COUNT; + public static final String STATUSBAR_HIDE_NOTCH = "statusbar_hide_notch"; + /** @hide */ + private static final Validator STATUSBAR_HIDE_NOTCH_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS} instead + * @hide + * Whether to set a lower brightness level when enabling night mode + * 0: Disabled + * 1: Set the brightness to a very low value + * 2: Set the brightness to a low value + * 3: Set the brightness to a medium value + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = - Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS; + public static final String NIGHT_BRIGHTNESS_VALUE = "night_brightness_value"; + /** @hide */ + public static final Validator NIGHT_BRIGHTNESS_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); /** - * @deprecated Use - * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED} instead + * Whether to enable status and navigation bar color in battery saver mode. + * Heads up timeout configuration + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = - Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED; + public static final String HEADS_UP_TIMEOUT = "heads_up_timeout"; + /** @hide */ + private static final Validator HEADS_UP_TIMEOUT_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS} - * instead + * Defines the global heads up notification snooze + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = - Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS; + public static final String HEADS_UP_NOTIFICATION_SNOOZE = "heads_up_notification_snooze"; + /** @hide */ + private static final Validator HEADS_UP_NOTIFICATION_SNOOZE_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} instead + * volume answer + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = - Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT; + public static final String ANSWER_VOLUME_BUTTON_BEHAVIOR_ANSWER = "call_volume_answer"; + /** @hide */ + private static final Validator ANSWER_VOLUME_BUTTON_BEHAVIOR_ANSWER_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_MAX_AP_CHECKS} - * instead + * Whether to scramble a pin unlock layout + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = Secure.WIFI_WATCHDOG_MAX_AP_CHECKS; + public static final String LOCKSCREEN_PIN_SCRAMBLE_LAYOUT = "lockscreen_scramble_pin_layout"; + /** @hide */ + private static final Validator LOCKSCREEN_PIN_SCRAMBLE_LAYOUT_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead + * Volume key controls ringtone or media sound stream + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_ON = Global.WIFI_WATCHDOG_ON; + public static final String VOLUME_KEYS_CONTROL_RING_TONE = + "volume_keys_control_ring_tone"; + /** @hide */ + private static final Validator VOLUME_KEYS_CONTROL_RING_TONE_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_PING_COUNT} instead + * Ambient screen settings + * "screen_brightness_array=0:1:2:3:4" + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_PING_COUNT = Secure.WIFI_WATCHDOG_PING_COUNT; + public static final String ALWAYS_ON_DISPLAY_CONSTANTS_CUST = "always_on_display_constants_cust"; /** - * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_PING_DELAY_MS} - * instead + * Whether to use blackaf themes in place of dark + * + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_PING_DELAY_MS = Secure.WIFI_WATCHDOG_PING_DELAY_MS; + public static final String USE_BLACKAF_THEME = "use_blackaf_theme"; + /** @hide */ + private static final Validator USE_BLACKAF_THEME_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_PING_TIMEOUT_MS} - * instead + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = - Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS; + public static final String USE_OLD_MOBILETYPE = "use_old_mobiletype"; + /** @hide */ + private static final Validator USE_OLD_MOBILETYPE_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Checks if the specified app can modify system settings. As of API - * level 23, an app cannot modify system settings unless it declares the - * {@link android.Manifest.permission#WRITE_SETTINGS} - * permission in its manifest, and the user specifically grants - * the app this capability. To prompt the user to grant this approval, - * the app must send an intent with the action {@link - * android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}, which causes - * the system to display a permission management screen. - * - * @param context App context. - * @return true if the calling app can write to system settings, false otherwise + * Screenshod sound enable, This is the noise made when taking a screesnhot + * Defaults to 0 - sounds disabled + * @hide */ - public static boolean canWrite(Context context) { - return isCallingPackageAllowedToWriteSettings(context, Process.myUid(), - context.getOpPackageName(), false); - } - } + public static final String SCREENSHOT_SHUTTER_SOUND = "screenshot_shutter_sound"; + /** @hide */ + private static final Validator SCREENSHOT_SHUTTER_SOUND_VALIDATOR = BOOLEAN_VALIDATOR; - /** - * Secure system settings, containing system preferences that applications - * can read but are not allowed to write. These are for preferences that - * the user must explicitly modify through the system UI or specialized - * APIs for those values, not modified directly by applications. - */ - public static final class Secure extends NameValueTable { - // NOTE: If you add new settings here, be sure to add them to - // com.android.providers.settings.SettingsProtoDumpUtil#dumpProtoSecureSettingsLocked. + /** + * Status bar carrier label + * 0: Hide + * 1: Display on keyguard status bar + * 2: Display on Normal status bar + * 3: Enabled for both + * @hide + */ + public static final String STATUS_BAR_SHOW_CARRIER = "status_bar_show_carrier"; + /** @hide */ + public static final Validator STATUS_BAR_SHOW_CARRIER_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); /** - * The content:// style URL for this table + * custom carrier label. The value is + * String. + * @hide */ - public static final Uri CONTENT_URI = - Uri.parse("content://" + AUTHORITY + "/secure"); + public static final String CUSTOM_CARRIER_LABEL = "custom_carrier_label"; + /** @hide */ + private static final Validator CUSTOM_CARRIER_LABEL_VALIDATOR = + ANY_STRING_VALIDATOR; - private static final ContentProviderHolder sProviderHolder = - new ContentProviderHolder(CONTENT_URI); + /** + * Whether to mute annoying notifications + * @hide + */ + public static final String MUTE_ANNOYING_NOTIFICATIONS_THRESHOLD = + "mute_annoying_notifications_threshold"; + /** @hide */ + public static final Validator MUTE_ANNOYING_NOTIFICATIONS_THRESHOLD_VALIDATOR = ANY_STRING_VALIDATOR; - // Populated lazily, guarded by class object: - private static final NameValueCache sNameValueCache = new NameValueCache( - CONTENT_URI, - CALL_METHOD_GET_SECURE, - CALL_METHOD_PUT_SECURE, - sProviderHolder); + /** + * Wheter to play notification sound and vibration if screen is ON + * 0 - never + * 1 - always + * @hide + */ + public static final String NOTIFICATION_SOUND_VIB_SCREEN_ON = "notification_sound_vib_screen_on"; + /** @hide */ + private static final Validator NOTIFICATION_SOUND_VIB_SCREEN_ON_VALIDATOR = + BOOLEAN_VALIDATOR; - private static ILockSettings sLockSettings = null; + /** + * @hide + */ + public static final String USE_BOTTOM_GESTURE_NAVIGATION = + "use_bottom_gesture_navigation"; + /** @hide */ + private static final Validator USE_BOTTOM_GESTURE_NAVIGATION_VALIDATOR = + BOOLEAN_VALIDATOR; - private static boolean sIsSystemProcess; - private static final HashSet MOVED_TO_LOCK_SETTINGS; - private static final HashSet MOVED_TO_GLOBAL; - static { - MOVED_TO_LOCK_SETTINGS = new HashSet<>(3); - MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_ENABLED); - MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_VISIBLE); - MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED); + /** + * @hide + */ + public static final String BOTTOM_GESTURE_TRIGGER_TIMEOUT = + "bottom_gesture_navigation_trigger_timeout"; + /** @hide */ + private static final Validator BOTTOM_GESTURE_TRIGGER_TIMEOUT_VALIDATOR = + ANY_INTEGER_VALIDATOR; - MOVED_TO_GLOBAL = new HashSet<>(); - MOVED_TO_GLOBAL.add(Settings.Global.ADB_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.ASSISTED_GPS_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.BLUETOOTH_ON); - MOVED_TO_GLOBAL.add(Settings.Global.BUGREPORT_IN_POWER_MENU); - MOVED_TO_GLOBAL.add(Settings.Global.CDMA_CELL_BROADCAST_SMS); - MOVED_TO_GLOBAL.add(Settings.Global.CDMA_ROAMING_MODE); - MOVED_TO_GLOBAL.add(Settings.Global.CDMA_SUBSCRIPTION_MODE); - MOVED_TO_GLOBAL.add(Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE); - MOVED_TO_GLOBAL.add(Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI); - MOVED_TO_GLOBAL.add(Settings.Global.DATA_ROAMING); - MOVED_TO_GLOBAL.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.DEVICE_PROVISIONED); - MOVED_TO_GLOBAL.add(Settings.Global.DISPLAY_SIZE_FORCED); - MOVED_TO_GLOBAL.add(Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE); - MOVED_TO_GLOBAL.add(Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE); - MOVED_TO_GLOBAL.add(Settings.Global.MOBILE_DATA); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_BUCKET_DURATION); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_DELETE_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_PERSIST_BYTES); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_ROTATE_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_POLL_INTERVAL); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_SAMPLE_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_BUCKET_DURATION); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_DELETE_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_PERSIST_BYTES); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_ROTATE_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_DELETE_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE); - MOVED_TO_GLOBAL.add(Settings.Global.NETWORK_PREFERENCE); - MOVED_TO_GLOBAL.add(Settings.Global.NITZ_UPDATE_DIFF); - MOVED_TO_GLOBAL.add(Settings.Global.NITZ_UPDATE_SPACING); - MOVED_TO_GLOBAL.add(Settings.Global.NTP_SERVER); - MOVED_TO_GLOBAL.add(Settings.Global.NTP_TIMEOUT); - MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_ERROR_POLL_COUNT); - MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS); - MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT); - MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS); - MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT); - MOVED_TO_GLOBAL.add(Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL); - MOVED_TO_GLOBAL.add(Settings.Global.SETUP_PREPAID_DETECTION_REDIR_HOST); - MOVED_TO_GLOBAL.add(Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL); - MOVED_TO_GLOBAL.add(Settings.Global.TETHER_DUN_APN); - MOVED_TO_GLOBAL.add(Settings.Global.TETHER_DUN_REQUIRED); - MOVED_TO_GLOBAL.add(Settings.Global.TETHER_SUPPORTED); - MOVED_TO_GLOBAL.add(Settings.Global.USB_MASS_STORAGE_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.USE_GOOGLE_MAIL); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_COUNTRY_CODE); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_FREQUENCY_BAND); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_IDLE_MS); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NUM_OPEN_NETWORKS_KEPT); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_ON); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_P2P_DEVICE_NAME); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SAVED_STATE); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_ENHANCED_AUTO_JOIN); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NETWORK_SHOW_RSSI); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_ON); - MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON); - MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_ENABLE); - MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_TIMEOUT); - MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE); - MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS); - MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS); - MOVED_TO_GLOBAL.add(Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS); - MOVED_TO_GLOBAL.add(Settings.Global.WTF_IS_FATAL); - MOVED_TO_GLOBAL.add(Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD); - MOVED_TO_GLOBAL.add(Settings.Global.BATTERY_DISCHARGE_THRESHOLD); - MOVED_TO_GLOBAL.add(Settings.Global.SEND_ACTION_APP_ERROR); - MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_AGE_SECONDS); - MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_MAX_FILES); - MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_QUOTA_KB); - MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_QUOTA_PERCENT); - MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_RESERVE_PERCENT); - MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_TAG_PREFIX); - MOVED_TO_GLOBAL.add(Settings.Global.ERROR_LOGCAT_PREFIX); - MOVED_TO_GLOBAL.add(Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL); - MOVED_TO_GLOBAL.add(Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD); - MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE); - MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES); - MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES); - MOVED_TO_GLOBAL.add(Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS); - MOVED_TO_GLOBAL.add(Settings.Global.CONNECTIVITY_CHANGE_DELAY); - MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED); - MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_SERVER); - MOVED_TO_GLOBAL.add(Settings.Global.NSD_ON); - MOVED_TO_GLOBAL.add(Settings.Global.SET_INSTALL_LOCATION); - MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_INSTALL_LOCATION); - MOVED_TO_GLOBAL.add(Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY); - MOVED_TO_GLOBAL.add(Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY); - MOVED_TO_GLOBAL.add(Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT); - MOVED_TO_GLOBAL.add(Settings.Global.HTTP_PROXY); - MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_HOST); - MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_PORT); - MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST); - MOVED_TO_GLOBAL.add(Settings.Global.SET_GLOBAL_HTTP_PROXY); - MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_DNS_SERVER); - MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_NETWORK_MODE); - MOVED_TO_GLOBAL.add(Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY); - } + /** + * Whether to display the kronic logo in the statusbar + * @hide + */ + public static final String STATUS_BAR_LOGO = "status_bar_logo"; + /** @hide */ + private static final Validator STATUS_BAR_LOGO_VALIDATOR = + BOOLEAN_VALIDATOR; + /** + * @hide + */ + public static final String BOTTOM_GESTURE_SWIPE_LIMIT = + "bottom_gesture_navigation_swipe_limit"; /** @hide */ - public static void getMovedToGlobalSettings(Set outKeySet) { - outKeySet.addAll(MOVED_TO_GLOBAL); - } + private static final Validator BOTTOM_GESTURE_SWIPE_LIMIT_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Whether to show network traffic indicator (in statusbar by default) + * @hide + */ + public static final String NETWORK_TRAFFIC_STATE = "network_traffic_state"; /** @hide */ - public static void clearProviderForTest() { - sProviderHolder.clearProviderForTest(); - sNameValueCache.clearGenerationTrackerForTest(); - } + private static final Validator NETWORK_TRAFFIC_STATE_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Look up a name in the database. - * @param resolver to access the database with - * @param name to look up in the table - * @return the corresponding value, or null if not present + * Whether to show network traffic indicator in expanded header + * @hide */ - public static String getString(ContentResolver resolver, String name) { - return getStringForUser(resolver, name, resolver.getUserId()); - } + public static final String NETWORK_TRAFFIC_VIEW_LOCATION = "network_traffic_view_location"; + /** + * Whether or not to hide the network traffic indicator when there is no activity + * @hide + */ + public static final String NETWORK_TRAFFIC_AUTOHIDE = "network_traffic_autohide"; /** @hide */ - public static String getStringForUser(ContentResolver resolver, String name, - int userHandle) { - if (MOVED_TO_GLOBAL.contains(name)) { - Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" - + " to android.provider.Settings.Global."); - return Global.getStringForUser(resolver, name, userHandle); - } + private static final Validator NETWORK_TRAFFIC_AUTOHIDE_VALIDATOR = + BOOLEAN_VALIDATOR; - if (MOVED_TO_LOCK_SETTINGS.contains(name)) { - synchronized (Secure.class) { - if (sLockSettings == null) { - sLockSettings = ILockSettings.Stub.asInterface( - (IBinder) ServiceManager.getService("lock_settings")); - sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID; - } - } - if (sLockSettings != null && !sIsSystemProcess) { - // No context; use the ActivityThread's context as an approximation for - // determining the target API level. - Application application = ActivityThread.currentApplication(); + /** + * Network traffic inactivity threshold (default is 1 kBs) + * @hide + */ + public static final String NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD = "network_traffic_autohide_threshold"; + /** @hide */ + private static final Validator NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD_VALIDATOR = + ANY_INTEGER_VALIDATOR; - boolean isPreMnc = application != null - && application.getApplicationInfo() != null - && application.getApplicationInfo().targetSdkVersion - <= VERSION_CODES.LOLLIPOP_MR1; - if (isPreMnc) { - try { - return sLockSettings.getString(name, "0", userHandle); - } catch (RemoteException re) { - // Fall through - } - } else { - throw new SecurityException("Settings.Secure." + name - + " is deprecated and no longer accessible." - + " See API documentation for potential replacements."); - } - } - } + /** + * Whether to disable showing arrows in network traffic indicators + * @hide + */ + public static final String NETWORK_TRAFFIC_HIDEARROW = "network_traffic_hidearrow"; + /** @hide */ + private static final Validator NETWORK_TRAFFIC_HIDEARROW_VALIDATOR = + BOOLEAN_VALIDATOR; - return sNameValueCache.getStringForUser(resolver, name, userHandle); - } + /** + * Whether allowing pocket service to register sensors and dispatch informations. + * 0 = disabled + * 1 = enabled + * @author Carlo Savignano + * @hide + */ + public static final String POCKET_JUDGE = "pocket_judge"; /** - * Store a name/value pair into the database. - * @param resolver to access the database with - * @param name to store - * @param value to associate with the name - * @return true if the value was set, false on database errors + * 0 - fullscreen + * 1 - partial + * @hide */ - public static boolean putString(ContentResolver resolver, String name, String value) { - return putStringForUser(resolver, name, value, resolver.getUserId()); - } + public static final String SCREENSHOT_DEFAULT_MODE = "screenshot_default_mode"; + /** @hide */ + public static final Validator SCREENSHOT_DEFAULT_MODE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 1); + /** + * Change quick settings tiles animation style + * + * @hide + */ + public static final String ANIM_TILE_STYLE = "anim_tile_style"; /** @hide */ - public static boolean putStringForUser(ContentResolver resolver, String name, String value, - int userHandle) { - return putStringForUser(resolver, name, value, null, false, userHandle); - } + private static final Validator ANIM_TILE_STYLE_VALIDATOR = + ANY_INTEGER_VALIDATOR; + /** + * Change quick settings tiles animation duration + * + * @hide + */ + public static final String ANIM_TILE_DURATION = "anim_tile_duration"; /** @hide */ - public static boolean putStringForUser(@NonNull ContentResolver resolver, - @NonNull String name, @Nullable String value, @Nullable String tag, - boolean makeDefault, @UserIdInt int userHandle) { - if (LOCATION_MODE.equals(name)) { - // Map LOCATION_MODE to underlying location provider storage API - return setLocationModeForUser(resolver, Integer.parseInt(value), userHandle); - } - if (MOVED_TO_GLOBAL.contains(name)) { - Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" - + " to android.provider.Settings.Global"); - return Global.putStringForUser(resolver, name, value, - tag, makeDefault, userHandle); - } - return sNameValueCache.putStringForUser(resolver, name, value, tag, - makeDefault, userHandle); - } + private static final Validator ANIM_TILE_DURATION_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * Store a name/value pair into the database. - *

- * The method takes an optional tag to associate with the setting - * which can be used to clear only settings made by your package and - * associated with this tag by passing the tag to {@link - * #resetToDefaults(ContentResolver, String)}. Anyone can override - * the current tag. Also if another package changes the setting - * then the tag will be set to the one specified in the set call - * which can be null. Also any of the settings setters that do not - * take a tag as an argument effectively clears the tag. - *

- * For example, if you set settings A and B with tags T1 and T2 and - * another app changes setting A (potentially to the same value), it + * Change quick settings tiles interpolator + * + * @hide + */ + public static final String ANIM_TILE_INTERPOLATOR = "anim_tile_interpolator"; + /** @hide */ + private static final Validator ANIM_TILE_INTERPOLATOR_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Whether to show the notification ticker on the status bar + * @hide + */ + public static final String STATUS_BAR_SHOW_TICKER = "status_bar_show_ticker"; + + /** @hide */ + private static final Validator STATUS_BAR_SHOW_TICKER_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * Ticker animation + * 0: Fade animation + * 1: Scrolling ticker + */ + public static final String STATUS_BAR_TICKER_ANIMATION_MODE = + "status_bar_ticker_animation_mode"; + + /** @hide */ + private static final Validator STATUS_BAR_TICKER_ANIMATION_MODE_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Status bar ticker duration in milliseconds. + * + * @hide + */ + public static final String STATUS_BAR_TICKER_TICK_DURATION = + "status_bar_ticker_tick_duration"; + + /** @hide */ + private static final Validator STATUS_BAR_TICKER_TICK_DURATION_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * whether to enable or disable vibration on succesful fingerprint auth + * + * @hide + */ + public static final String FINGERPRINT_SUCCESS_VIB = "fingerprint_success_vib"; + /** @hide */ + private static final Validator FINGERPRINT_SUCCESS_VIB_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether to allow one finger quick settings expansion on the right side of the statusbar. + * @hide + */ + public static final String STATUS_BAR_QUICK_QS_PULLDOWN = "status_bar_quick_qs_pulldown"; + /** @hide */ + public static final Validator STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); + + /** + * Quick Settings Smart Pulldown + * @hide + */ + public static final String QS_SMART_PULLDOWN = "qs_smart_pulldown"; + /** @hide */ + public static final Validator QS_SMART_PULLDOWN_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); + + /** + * @hide + */ + public static final String SCREENRECORD_QUALITY_MODE = "screenrecord_quality_mode"; + /** @hide */ + private static final Validator SCREENRECORD_QUALITY_MODE_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * @hide + */ + public static final String FULL_GESTURE_NAVBAR = "full_gesture_navbar"; + /** @hide */ + private static final Validator FULL_GESTURE_NAVBAR_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * @hide + */ + public static final String FULL_GESTURE_NAVBAR_DT2S = "full_gesture_navbar_dt2s"; + /** @hide */ + private static final Validator FULL_GESTURE_NAVBAR_DT2S_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Statusbar logo Style + * @hide + */ + public static final String STATUS_BAR_LOGO_STYLE = "status_bar_logo_style"; + + + /** + * Disable expanding quick settings on secure lock screens + * + * @hide + */ + public static final String LOCK_QS_DISABLED = "lockscreen_qs_disabled"; + /** @hide */ + private static final Validator LOCK_QS_DISABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether to wake the display when plugging or unplugging the charger + * + * @hide + */ + public static final String WAKE_WHEN_PLUGGED_OR_UNPLUGGED = "wake_when_plugged_or_unplugged"; + /** @hide */ + private static final Validator WAKE_WHEN_PLUGGED_OR_UNPLUGGED_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Enable face auto unlock on secure lock screens + * + * @hide + */ + public static final String DISPLAY_MODE = "display_mode"; + + private static final Validator DISPLAY_MODE_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Whether to use icon pack for Recents + * @hide + */ + public static final String RECENTS_ICON_PACK = "recents_icon_pack"; + + /** + * Status bar brightness control. + * @hide + */ + public static final String STATUS_BAR_BRIGHTNESS_CONTROL = "status_bar_brightness_control"; + /** @hide */ + public static final Validator STATUS_BAR_BRIGHTNESS_CONTROL_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * The enabled mode for the theme tile. + * - ACCENT + * - STYLE + * @hide + */ + public static final String THEME_TILE_ENABLED_MODE = "theme_tile_enabled_mode"; + + /** + * Custom Ambient tilt gesture + * @hide + */ + public static final String CUSTOM_AMBIENT_TILT_GESTURE = "custom_ambient_tilt_gesture"; + + /** + * Custom Ambient handwave gesture + * @hide + */ + public static final String CUSTOM_AMBIENT_HANDWAVE_GESTURE = "custom_ambient_handwave_gesture"; + + /** + * Custom Ambient pocketmode gesture + * @hide + */ + public static final String CUSTOM_AMBIENT_POCKETMODE_GESTURE = "custom_ambient_pocketmode_gesture"; + + /** + * Battery Estimate + * @hide + */ + public static final String SHOW_BATTERY_ESTIMATE = "show_battery_estimate"; + + /** + * Battery Estimate Position + * @hide + */ + public static final String BATTERY_ESTIMATE_POSITION = "battery_estimate_position"; + + /** + * Whether to enable gaming mode or not + * + * @hide + */ + public static final String ENABLE_GAMING_MODE = "enable_gaming_mode"; + + /** + * Force an Ambient notification when a new media track is being played + * 0 - disabled + * 1 - show track info within normal Ambient Display and force a new Ambient clean layout when skipping tracks + * @hide + */ + public static final String FORCE_AMBIENT_FOR_MEDIA = "force_ambient_for_media"; + /** @hide */ + private static final Validator FORCE_AMBIENT_FOR_MEDIA_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether to vibrate on power connection or disconnection + * @hide + */ + public static final String VIBRATION_ON_CHARGE_STATE_CHANGED = "vibration_on_charge_state_changed"; + /** @hide */ + private static final Validator VIBRATION_ON_CHARGE_STATE_CHANGED_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether to blink flashlight for incoming calls + * 0 = Disabled (Default) + * 1 = Blink flashlight only in Ringer mode + * 2 = Blink flashlight only in DND mode + * 3 = Blink flashlight always regardless of ringer mode + * @hide + */ + public static final String FLASHLIGHT_ON_CALL = "flashlight_on_call"; + /** @hide */ + public static final Validator FLASHLIGHT_ON_CALL_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 3); + + /** + * Whether to display cross sign for a data disabled connection + * @hide + */ + public static final String DATA_DISABLED_ICON = "data_disabled_icon"; + + /** + * Whether the phone ringtone should be played in an increasing manner + * @hide + */ + public static final String INCREASING_RING = "increasing_ring"; + /** @hide */ + public static final Validator INCREASING_RING_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Start volume fraction for increasing ring volume + * @hide + */ + public static final String INCREASING_RING_START_VOLUME = "increasing_ring_start_vol"; + /** @hide */ + public static final Validator INCREASING_RING_START_VOLUME_VALIDATOR = + ANY_STRING_VALIDATOR; + + /** + * Ramp up time (seconds) for increasing ring + * @hide + */ + public static final String INCREASING_RING_RAMP_UP_TIME = "increasing_ring_ramp_up_time"; + /** @hide */ + public static final Validator INCREASING_RING_RAMP_UP_TIME_VALIDATOR = + ANY_STRING_VALIDATOR; + + /** + * Whether to launch default music player when headset plugged in + * 0 = don't do anything (default) + * 1 = launch only on wired connection + * 2 = launch only on bt connection but no carkit + * 3 = launch only on bt connection + * 4 = launch on both connection types but no carkit + * 5 = launch on both connection types + * @hide + */ + public static final String HEADSET_CONNECT_PLAYER = "headset_connect_player"; + + /** + * Whether the phone vibrates on call connect + * @hide + */ + public static final String VIBRATE_ON_CONNECT = "vibrate_on_connect"; + /** @hide */ + public static final Validator VIBRATE_ON_CONNECT_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether the phone vibrates on call waiting + * @hide + */ + public static final String VIBRATE_ON_CALLWAITING = "vibrate_on_callwaiting"; + /** @hide */ + public static final Validator VIBRATE_ON_CALLWAITING_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether the phone vibrates on disconnect + * @hide + */ + public static final String VIBRATE_ON_DISCONNECT = "vibrate_on_disconnect"; + /** @hide */ + public static final Validator VIBRATE_ON_DISCONNECT_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Position of date + * 0 - Left of clock + * 1 - Right of clock + * @hide + */ + public static final String STATUSBAR_CLOCK_DATE_POSITION = "statusbar_clock_date_position"; + /** @hide */ + public static final Validator STATUSBAR_CLOCK_DATE_POSITION_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Whether to enable DOZE only when charging + * @hide + */ + public static final String DOZE_ON_CHARGE = "doze_on_charge"; + + private static final Validator DOZE_ON_CHARGE_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * hidden stting of the current state of DOZE only when charging + * @hide + */ + public static final String DOZE_ON_CHARGE_NOW = "doze_on_charge_now"; + + /** + * Three Finger Gesture from Oppo + * @hide + */ + public static final String THREE_FINGER_GESTURE = "three_finger_gesture"; + /** @hide */ + public static final Validator THREE_FINGER_GESTURE_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * Applications list where heasdup should't show + * + * @hide + */ + public static final String HEADS_UP_STOPLIST_VALUES = "heads_up_stoplist_values"; + + /** + * Which applications to disable heads up notifications for + * + * @hide + */ + public static final String HEADS_UP_BLACKLIST_VALUES = "heads_up_blacklist_values"; + + /** + * Volume keys control cursor in text fields (default is 0) + * 0 - Disabled + * 1 - Volume up/down moves cursor left/right + * 2 - Volume up/down moves cursor right/left + * @hide + */ + public static final String VOLUME_KEY_CURSOR_CONTROL = "volume_key_cursor_control"; + /** @hide */ + public static final Validator VOLUME_KEY_CURSOR_CONTROL_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); + + /** + * Which component to use for Recents UI + * 0 - Pie Recents (Quickstep) + * 1 - Oreo Recents (SystemUI) + * @hide + */ + public static final String RECENTS_COMPONENT = "recents_component"; + /** @hide */ + public static final Validator RECENTS_COMPONENT_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 1); + + /** + * Weather to use a custom color for the visualizer on the lock screen + * @hide + */ + public static final String LOCK_SCREEN_VISUALIZER_USE_CUSTOM_COLOR = "lock_screen_visualizer_use_custom_color"; + + /** + * Custom color of the visualizer on the lock screen + * @hide + */ + public static final String LOCK_SCREEN_VISUALIZER_CUSTOM_COLOR = "lock_screen_visualizer_custom_color"; + + /** + * modify how the album art shows up on lockscreen + * 0 - default + * 1 - grayscale + * 2 - blurry + * @hide + */ + public static final String LOCKSCREEN_ALBUM_ART_FILTER = "lockscreen_album_art_filter"; + + /** + * Whether to show the kill app button in notification guts + * + * @hide + */ + public static final String NOTIFICATION_GUTS_KILL_APP_BUTTON = + "notification_guts_kill_app_button"; + + /** + + /** + * Whether to change the transparency of the qs panel + * @hide + */ + public static final String QS_PANEL_BG_ALPHA = "qs_panel_bg_alpha"; + + /** @hide */ + + private static final Validator QS_PANEL_BG_ALPHA_VALIDATOR = + ANY_INTEGER_VALIDATOR; + + /** + * Settings to backup. This is here so that it's in the same place as the settings + * keys and easy to update. + * + * NOTE: Settings are backed up and restored in the order they appear + * in this array. If you have one setting depending on another, + * make sure that they are ordered appropriately. + * + * @hide + */ + public static final String[] SETTINGS_TO_BACKUP = { + STAY_ON_WHILE_PLUGGED_IN, // moved to global + WIFI_USE_STATIC_IP, + WIFI_STATIC_IP, + WIFI_STATIC_GATEWAY, + WIFI_STATIC_NETMASK, + WIFI_STATIC_DNS1, + WIFI_STATIC_DNS2, + BLUETOOTH_DISCOVERABILITY, + BLUETOOTH_DISCOVERABILITY_TIMEOUT, + FONT_SCALE, + DIM_SCREEN, + SCREEN_OFF_TIMEOUT, + SCREEN_BRIGHTNESS_MODE, + SCREEN_AUTO_BRIGHTNESS_ADJ, + SCREEN_BRIGHTNESS_FOR_VR, + VIBRATE_INPUT_DEVICES, + MODE_RINGER_STREAMS_AFFECTED, + TEXT_AUTO_REPLACE, + TEXT_AUTO_CAPS, + TEXT_AUTO_PUNCTUATE, + TEXT_SHOW_PASSWORD, + AUTO_TIME, // moved to global + AUTO_TIME_ZONE, // moved to global + TIME_12_24, + DATE_FORMAT, + DTMF_TONE_WHEN_DIALING, + DTMF_TONE_TYPE_WHEN_DIALING, + HEARING_AID, + TTY_MODE, + MASTER_MONO, + SOUND_EFFECTS_ENABLED, + HAPTIC_FEEDBACK_ENABLED, + POWER_SOUNDS_ENABLED, // moved to global + DOCK_SOUNDS_ENABLED, // moved to global + LOCKSCREEN_SOUNDS_ENABLED, + SHOW_WEB_SUGGESTIONS, + SIP_CALL_OPTIONS, + SIP_RECEIVE_CALLS, + POINTER_SPEED, + VIBRATE_WHEN_RINGING, + RINGTONE, + RINGTONE2, + LOCK_TO_APP_ENABLED, + NOTIFICATION_LIGHT_PULSE, + NOTIFICATION_SOUND, + ACCELEROMETER_ROTATION, + SHOW_BATTERY_PERCENT, + NOTIFICATION_VIBRATION_INTENSITY, + HAPTIC_FEEDBACK_INTENSITY, + DISPLAY_COLOR_MODE, + ACCELEROMETER_ROTATION_ANGLES, + ANIM_TILE_STYLE, + ANIM_TILE_DURATION, + ANIM_TILE_INTERPOLATOR, + ANSWER_VOLUME_BUTTON_BEHAVIOR_ANSWER, + BATTERY_LIGHT_ENABLED, + BATTERY_LIGHT_ALLOW_ON_DND, + BATTERY_LIGHT_LOW_BLINKING, + BATTERY_LIGHT_LOW_COLOR, + BATTERY_LIGHT_MEDIUM_COLOR, + BATTERY_LIGHT_FULL_COLOR, + BATTERY_LIGHT_REALLYFULL_COLOR, + BOTTOM_GESTURE_TRIGGER_TIMEOUT, + BOTTOM_GESTURE_SWIPE_LIMIT, + BOTTOM_GESTURE_SWIPE_START, + BOTTOM_GESTURE_FEEDBACK_DURATION, + CUSTOM_CARRIER_LABEL, + DISPLAY_MODE, + DOUBLE_TAP_SLEEP_GESTURE, + DOUBLE_TAP_SLEEP_ANYWHERE, + FINGERPRINT_SUCCESS_VIB, + FORCE_AMBIENT_FOR_MEDIA, + FULL_GESTURE_NAVBAR, + FULL_GESTURE_NAVBAR_DT2S, + HEADS_UP_TIMEOUT, + HEADS_UP_NOTIFICATION_SNOOZE, + INCREASING_RING, + INCREASING_RING_START_VOLUME, + INCREASING_RING_RAMP_UP_TIME, + LOCK_QS_DISABLED, + LOCKSCREEN_CLOCK, + LOCKSCREEN_CLOCK_SELECTION, + LOCKSCREEN_INFO, + LOCKSCREEN_CHARGING_CURRENT, + LOCKSCREEN_MEDIA_METADATA, + LOCKSCREEN_PIN_SCRAMBLE_LAYOUT, + NETWORK_TRAFFIC_STATE, + NETWORK_TRAFFIC_AUTOHIDE, + NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD, + NETWORK_TRAFFIC_HIDEARROW, + MUTE_ANNOYING_NOTIFICATIONS_THRESHOLD, + NOTIFICATION_SOUND_VIB_SCREEN_ON, + POWERMENU_SCREENSHOT, + POWERMENU_AIRPLANE, + POWERMENU_ADVANCED_REBOOT, + POWERMENU_REBOOT, + QS_LAYOUT_ROWS, + QS_LAYOUT_ROWS_LANDSCAPE, + QS_LAYOUT_COLUMNS_LANDSCAPE, + QS_LAYOUT_COLUMNS, + QS_SMART_PULLDOWN, + QS_TILE_HIDE_TITLE, + QS_QUICKBAR_COLUMNS, + RECENTS_CLEAR_ALL_LOCATION, + RECENTS_COMPONENT, + SCREENSHOT_DEFAULT_MODE, + SCREENSHOT_SHUTTER_SOUND, + SCREENRECORD_QUALITY_MODE, + SHOW_CLEAR_ALL_RECENTS, + SHOW_FOURG, + SHOW_VOLTE_ICON, + STATUS_BAR_CLOCK, + STATUS_BAR_CLOCK_SECONDS, + STATUSBAR_CLOCK_STYLE, + STATUSBAR_CLOCK_AM_PM_STYLE, + STATUSBAR_CLOCK_DATE_DISPLAY, + STATUSBAR_CLOCK_DATE_STYLE, + STATUSBAR_CLOCK_DATE_FORMAT, + STATUSBAR_CLOCK_DATE_POSITION, + STATUSBAR_HIDE_NOTCH, + STATUS_BAR_BRIGHTNESS_CONTROL, + STATUS_BAR_LOGO, + STATUS_BAR_SHOW_CARRIER, + STATUS_BAR_QUICK_QS_PULLDOWN, + STATUS_BAR_SHOW_TICKER, + STATUS_BAR_TICKER_ANIMATION_MODE, + STATUS_BAR_TICKER_TICK_DURATION, + SWAP_VOLUME_BUTTONS, + THREE_FINGER_GESTURE, + TOAST_ICON, + USE_OLD_MOBILETYPE, + VIBRATE_ON_CONNECT, + VIBRATE_ON_CALLWAITING, + VIBRATE_ON_DISCONNECT, + VIBRATION_ON_CHARGE_STATE_CHANGED, + VOLUME_BUTTON_MUSIC_CONTROL, + VOLUME_KEYS_CONTROL_RING_TONE, + VOLUME_KEY_CURSOR_CONTROL, + VOLUME_ROCKER_WAKE, + WAKE_WHEN_PLUGGED_OR_UNPLUGGED, + DOZE_ON_CHARGE, + QS_PANEL_BG_ALPHA + }; + + /** + * Keys we no longer back up under the current schema, but want to continue to + * process when restoring historical backup datasets. + * + * All settings in {@link LEGACY_RESTORE_SETTINGS} array *must* have a non-null validator, + * otherwise they won't be restored. + * + * @hide + */ + public static final String[] LEGACY_RESTORE_SETTINGS = { + }; + + /** + * These are all public system settings + * + * @hide + */ + public static final Set PUBLIC_SETTINGS = new ArraySet<>(); + static { + PUBLIC_SETTINGS.add(END_BUTTON_BEHAVIOR); + PUBLIC_SETTINGS.add(WIFI_USE_STATIC_IP); + PUBLIC_SETTINGS.add(WIFI_STATIC_IP); + PUBLIC_SETTINGS.add(WIFI_STATIC_GATEWAY); + PUBLIC_SETTINGS.add(WIFI_STATIC_NETMASK); + PUBLIC_SETTINGS.add(WIFI_STATIC_DNS1); + PUBLIC_SETTINGS.add(WIFI_STATIC_DNS2); + PUBLIC_SETTINGS.add(BLUETOOTH_DISCOVERABILITY); + PUBLIC_SETTINGS.add(BLUETOOTH_DISCOVERABILITY_TIMEOUT); + PUBLIC_SETTINGS.add(NEXT_ALARM_FORMATTED); + PUBLIC_SETTINGS.add(FONT_SCALE); + PUBLIC_SETTINGS.add(DIM_SCREEN); + PUBLIC_SETTINGS.add(SCREEN_OFF_TIMEOUT); + PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS); + PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_FOR_VR); + PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_MODE); + PUBLIC_SETTINGS.add(MODE_RINGER_STREAMS_AFFECTED); + PUBLIC_SETTINGS.add(MUTE_STREAMS_AFFECTED); + PUBLIC_SETTINGS.add(VIBRATE_ON); + PUBLIC_SETTINGS.add(VOLUME_RING); + PUBLIC_SETTINGS.add(VOLUME_SYSTEM); + PUBLIC_SETTINGS.add(VOLUME_VOICE); + PUBLIC_SETTINGS.add(VOLUME_MUSIC); + PUBLIC_SETTINGS.add(VOLUME_ALARM); + PUBLIC_SETTINGS.add(VOLUME_NOTIFICATION); + PUBLIC_SETTINGS.add(VOLUME_BLUETOOTH_SCO); + PUBLIC_SETTINGS.add(RINGTONE); + PUBLIC_SETTINGS.add(RINGTONE2); + PUBLIC_SETTINGS.add(NOTIFICATION_SOUND); + PUBLIC_SETTINGS.add(ALARM_ALERT); + PUBLIC_SETTINGS.add(TEXT_AUTO_REPLACE); + PUBLIC_SETTINGS.add(TEXT_AUTO_CAPS); + PUBLIC_SETTINGS.add(TEXT_AUTO_PUNCTUATE); + PUBLIC_SETTINGS.add(TEXT_SHOW_PASSWORD); + PUBLIC_SETTINGS.add(SHOW_GTALK_SERVICE_STATUS); + PUBLIC_SETTINGS.add(WALLPAPER_ACTIVITY); + PUBLIC_SETTINGS.add(TIME_12_24); + PUBLIC_SETTINGS.add(DATE_FORMAT); + PUBLIC_SETTINGS.add(SETUP_WIZARD_HAS_RUN); + PUBLIC_SETTINGS.add(ACCELEROMETER_ROTATION); + PUBLIC_SETTINGS.add(USER_ROTATION); + PUBLIC_SETTINGS.add(DTMF_TONE_WHEN_DIALING); + PUBLIC_SETTINGS.add(SOUND_EFFECTS_ENABLED); + PUBLIC_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED); + PUBLIC_SETTINGS.add(SHOW_WEB_SUGGESTIONS); + PUBLIC_SETTINGS.add(VIBRATE_WHEN_RINGING); + PUBLIC_SETTINGS.add(ACCELEROMETER_ROTATION_ANGLES); + PUBLIC_SETTINGS.add(ANIM_TILE_STYLE); + PUBLIC_SETTINGS.add(ANIM_TILE_DURATION); + PUBLIC_SETTINGS.add(ANIM_TILE_INTERPOLATOR); + PUBLIC_SETTINGS.add(ANSWER_VOLUME_BUTTON_BEHAVIOR_ANSWER); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_ENABLED); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_ALLOW_ON_DND); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_LOW_BLINKING); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_LOW_COLOR); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_MEDIUM_COLOR); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_FULL_COLOR); + PUBLIC_SETTINGS.add(BATTERY_LIGHT_REALLYFULL_COLOR); + PUBLIC_SETTINGS.add(BOTTOM_GESTURE_SWIPE_LIMIT); + PUBLIC_SETTINGS.add(BOTTOM_GESTURE_SWIPE_START); + PUBLIC_SETTINGS.add(BOTTOM_GESTURE_TRIGGER_TIMEOUT); + PUBLIC_SETTINGS.add(BOTTOM_GESTURE_FEEDBACK_DURATION); + PUBLIC_SETTINGS.add(CUSTOM_CARRIER_LABEL); + PUBLIC_SETTINGS.add(DOUBLE_TAP_SLEEP_ANYWHERE); + PUBLIC_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE); + PUBLIC_SETTINGS.add(FINGERPRINT_SUCCESS_VIB); + PUBLIC_SETTINGS.add(FORCE_AMBIENT_FOR_MEDIA); + PUBLIC_SETTINGS.add(FULL_GESTURE_NAVBAR); + PUBLIC_SETTINGS.add(FULL_GESTURE_NAVBAR_DT2S); + PUBLIC_SETTINGS.add(HEADS_UP_NOTIFICATION_SNOOZE); + PUBLIC_SETTINGS.add(HEADS_UP_TIMEOUT); + PUBLIC_SETTINGS.add(INCREASING_RING); + PUBLIC_SETTINGS.add(INCREASING_RING_START_VOLUME); + PUBLIC_SETTINGS.add(INCREASING_RING_RAMP_UP_TIME); + PUBLIC_SETTINGS.add(LOCK_QS_DISABLED); + PUBLIC_SETTINGS.add(LOCKSCREEN_CLOCK); + PUBLIC_SETTINGS.add(LOCKSCREEN_CLOCK_SELECTION); + PUBLIC_SETTINGS.add(LOCKSCREEN_CHARGING_CURRENT); + PUBLIC_SETTINGS.add(LOCKSCREEN_INFO); + PUBLIC_SETTINGS.add(LOCKSCREEN_MEDIA_METADATA); + PUBLIC_SETTINGS.add(LOCKSCREEN_PIN_SCRAMBLE_LAYOUT); + PUBLIC_SETTINGS.add(MUTE_ANNOYING_NOTIFICATIONS_THRESHOLD); + PUBLIC_SETTINGS.add(NETWORK_TRAFFIC_AUTOHIDE); + PUBLIC_SETTINGS.add(NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD); + PUBLIC_SETTINGS.add(NETWORK_TRAFFIC_HIDEARROW); + PUBLIC_SETTINGS.add(NETWORK_TRAFFIC_STATE); + PUBLIC_SETTINGS.add(NOTIFICATION_SOUND_VIB_SCREEN_ON); + PUBLIC_SETTINGS.add(POWERMENU_ADVANCED_REBOOT); + PUBLIC_SETTINGS.add(POWERMENU_AIRPLANE); + PUBLIC_SETTINGS.add(POWERMENU_REBOOT); + PUBLIC_SETTINGS.add(POWERMENU_SCREENSHOT); + PUBLIC_SETTINGS.add(QS_LAYOUT_ROWS); + PUBLIC_SETTINGS.add(QS_LAYOUT_ROWS_LANDSCAPE); + PUBLIC_SETTINGS.add(QS_LAYOUT_COLUMNS); + PUBLIC_SETTINGS.add(QS_LAYOUT_COLUMNS_LANDSCAPE); + PUBLIC_SETTINGS.add(QS_QUICKBAR_COLUMNS); + PUBLIC_SETTINGS.add(QS_SMART_PULLDOWN); + PUBLIC_SETTINGS.add(QS_TILE_HIDE_TITLE); + PUBLIC_SETTINGS.add(RECENTS_CLEAR_ALL_LOCATION); + PUBLIC_SETTINGS.add(RECENTS_COMPONENT); + PUBLIC_SETTINGS.add(SCREENSHOT_DEFAULT_MODE); + PUBLIC_SETTINGS.add(SCREENSHOT_SHUTTER_SOUND); + PUBLIC_SETTINGS.add(SCREENRECORD_QUALITY_MODE); + PUBLIC_SETTINGS.add(SHOW_CLEAR_ALL_RECENTS); + PUBLIC_SETTINGS.add(SHOW_FOURG); + PUBLIC_SETTINGS.add(SHOW_VOLTE_ICON); + PUBLIC_SETTINGS.add(STATUS_BAR_BRIGHTNESS_CONTROL); + PUBLIC_SETTINGS.add(STATUS_BAR_QUICK_QS_PULLDOWN); + PUBLIC_SETTINGS.add(STATUS_BAR_SHOW_CARRIER); + PUBLIC_SETTINGS.add(STATUS_BAR_CLOCK); + PUBLIC_SETTINGS.add(STATUSBAR_CLOCK_STYLE); + PUBLIC_SETTINGS.add(STATUS_BAR_CLOCK_SECONDS); + PUBLIC_SETTINGS.add(STATUSBAR_CLOCK_AM_PM_STYLE); + PUBLIC_SETTINGS.add(STATUSBAR_CLOCK_DATE_DISPLAY); + PUBLIC_SETTINGS.add(STATUSBAR_CLOCK_DATE_STYLE); + PUBLIC_SETTINGS.add(STATUSBAR_CLOCK_DATE_FORMAT); + PUBLIC_SETTINGS.add(STATUSBAR_CLOCK_DATE_POSITION); + PUBLIC_SETTINGS.add(STATUSBAR_HIDE_NOTCH); + PUBLIC_SETTINGS.add(SWAP_VOLUME_BUTTONS); + PUBLIC_SETTINGS.add(TOAST_ICON); + PUBLIC_SETTINGS.add(STATUS_BAR_SHOW_TICKER); + PUBLIC_SETTINGS.add(STATUS_BAR_TICKER_ANIMATION_MODE); + PUBLIC_SETTINGS.add(STATUS_BAR_TICKER_TICK_DURATION); + PUBLIC_SETTINGS.add(THREE_FINGER_GESTURE); + PUBLIC_SETTINGS.add(USE_BLACKAF_THEME); + PUBLIC_SETTINGS.add(USE_BOTTOM_GESTURE_NAVIGATION); + PUBLIC_SETTINGS.add(USE_OLD_MOBILETYPE); + PUBLIC_SETTINGS.add(VIBRATE_ON_CONNECT); + PUBLIC_SETTINGS.add(VIBRATE_ON_CALLWAITING); + PUBLIC_SETTINGS.add(VIBRATE_ON_DISCONNECT); + PUBLIC_SETTINGS.add(VIBRATION_ON_CHARGE_STATE_CHANGED); + PUBLIC_SETTINGS.add(VOLUME_BUTTON_MUSIC_CONTROL); + PUBLIC_SETTINGS.add(VOLUME_KEYS_CONTROL_RING_TONE); + PUBLIC_SETTINGS.add(VOLUME_KEY_CURSOR_CONTROL); + PUBLIC_SETTINGS.add(VOLUME_ROCKER_WAKE); + PUBLIC_SETTINGS.add(WAKE_WHEN_PLUGGED_OR_UNPLUGGED); + PUBLIC_SETTINGS.add(CUSTOM_BUTTON_BRIGHTNESS); + PUBLIC_SETTINGS.add(CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS); + PUBLIC_SETTINGS.add(BUTTON_BACKLIGHT_ENABLE); + PUBLIC_SETTINGS.add(BUTTON_BACKLIGHT_TIMEOUT); + PUBLIC_SETTINGS.add(BUTTON_BACKLIGHT_ON_TOUCH_ONLY); + PUBLIC_SETTINGS.add(STATUS_BAR_LOGO); + } + + /** + * These are all hidden system settings. + * + * @hide + */ + public static final Set PRIVATE_SETTINGS = new ArraySet<>(); + static { + PRIVATE_SETTINGS.add(WIFI_USE_STATIC_IP); + PRIVATE_SETTINGS.add(END_BUTTON_BEHAVIOR); + PRIVATE_SETTINGS.add(ADVANCED_SETTINGS); + PRIVATE_SETTINGS.add(SCREEN_AUTO_BRIGHTNESS_ADJ); + PRIVATE_SETTINGS.add(VIBRATE_INPUT_DEVICES); + PRIVATE_SETTINGS.add(VOLUME_MASTER); + PRIVATE_SETTINGS.add(MASTER_MONO); + PRIVATE_SETTINGS.add(NOTIFICATIONS_USE_RING_VOLUME); + PRIVATE_SETTINGS.add(VIBRATE_IN_SILENT); + PRIVATE_SETTINGS.add(MEDIA_BUTTON_RECEIVER); + PRIVATE_SETTINGS.add(HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY); + PRIVATE_SETTINGS.add(DTMF_TONE_TYPE_WHEN_DIALING); + PRIVATE_SETTINGS.add(HEARING_AID); + PRIVATE_SETTINGS.add(TTY_MODE); + PRIVATE_SETTINGS.add(NOTIFICATION_LIGHT_PULSE); + PRIVATE_SETTINGS.add(POINTER_LOCATION); + PRIVATE_SETTINGS.add(SHOW_TOUCHES); + PRIVATE_SETTINGS.add(WINDOW_ORIENTATION_LISTENER_LOG); + PRIVATE_SETTINGS.add(POWER_SOUNDS_ENABLED); + PRIVATE_SETTINGS.add(DOCK_SOUNDS_ENABLED); + PRIVATE_SETTINGS.add(LOCKSCREEN_SOUNDS_ENABLED); + PRIVATE_SETTINGS.add(LOCKSCREEN_DISABLED); + PRIVATE_SETTINGS.add(LOW_BATTERY_SOUND); + PRIVATE_SETTINGS.add(DESK_DOCK_SOUND); + PRIVATE_SETTINGS.add(DESK_UNDOCK_SOUND); + PRIVATE_SETTINGS.add(CAR_DOCK_SOUND); + PRIVATE_SETTINGS.add(CAR_UNDOCK_SOUND); + PRIVATE_SETTINGS.add(LOCK_SOUND); + PRIVATE_SETTINGS.add(UNLOCK_SOUND); + PRIVATE_SETTINGS.add(SIP_RECEIVE_CALLS); + PRIVATE_SETTINGS.add(SIP_CALL_OPTIONS); + PRIVATE_SETTINGS.add(SIP_ALWAYS); + PRIVATE_SETTINGS.add(SIP_ADDRESS_ONLY); + PRIVATE_SETTINGS.add(SIP_ASK_ME_EACH_TIME); + PRIVATE_SETTINGS.add(POINTER_SPEED); + PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED); + PRIVATE_SETTINGS.add(EGG_MODE); + PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT); + PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE); + PRIVATE_SETTINGS.add(DOZE_ON_CHARGE); + PRIVATE_SETTINGS.add(HEADSET_CONNECT_PLAYER); + PRIVATE_SETTINGS.add(QS_PANEL_BG_ALPHA); + + // Pocket mode handler. + PRIVATE_SETTINGS.add(POCKET_JUDGE); + PRIVATE_SETTINGS.add(DISPLAY_MODE); + } + + /** + * These are all public system settings + * + * All settings in {@link SETTINGS_TO_BACKUP} array *must* have a non-null validator, + * otherwise they won't be restored. + * + * @hide + */ + public static final Map VALIDATORS = new ArrayMap<>(); + static { + VALIDATORS.put(STAY_ON_WHILE_PLUGGED_IN, STAY_ON_WHILE_PLUGGED_IN_VALIDATOR); + VALIDATORS.put(END_BUTTON_BEHAVIOR, END_BUTTON_BEHAVIOR_VALIDATOR); + VALIDATORS.put(WIFI_USE_STATIC_IP, WIFI_USE_STATIC_IP_VALIDATOR); + VALIDATORS.put(BLUETOOTH_DISCOVERABILITY, BLUETOOTH_DISCOVERABILITY_VALIDATOR); + VALIDATORS.put(BLUETOOTH_DISCOVERABILITY_TIMEOUT, + BLUETOOTH_DISCOVERABILITY_TIMEOUT_VALIDATOR); + VALIDATORS.put(NEXT_ALARM_FORMATTED, NEXT_ALARM_FORMATTED_VALIDATOR); + VALIDATORS.put(FONT_SCALE, FONT_SCALE_VALIDATOR); + VALIDATORS.put(DIM_SCREEN, DIM_SCREEN_VALIDATOR); + VALIDATORS.put(DISPLAY_COLOR_MODE, DISPLAY_COLOR_MODE_VALIDATOR); + VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR); + VALIDATORS.put(SCREEN_BRIGHTNESS_FOR_VR, SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR); + VALIDATORS.put(SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_VALIDATOR); + VALIDATORS.put(MODE_RINGER_STREAMS_AFFECTED, MODE_RINGER_STREAMS_AFFECTED_VALIDATOR); + VALIDATORS.put(MUTE_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED_VALIDATOR); + VALIDATORS.put(VIBRATE_ON, VIBRATE_ON_VALIDATOR); + VALIDATORS.put(NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); + VALIDATORS.put(HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_VALIDATOR); + VALIDATORS.put(RINGTONE, RINGTONE_VALIDATOR); + VALIDATORS.put(RINGTONE2, RINGTONE_VALIDATOR); + VALIDATORS.put(NOTIFICATION_SOUND, NOTIFICATION_SOUND_VALIDATOR); + VALIDATORS.put(ALARM_ALERT, ALARM_ALERT_VALIDATOR); + VALIDATORS.put(TEXT_AUTO_REPLACE, TEXT_AUTO_REPLACE_VALIDATOR); + VALIDATORS.put(TEXT_AUTO_CAPS, TEXT_AUTO_CAPS_VALIDATOR); + VALIDATORS.put(TEXT_AUTO_PUNCTUATE, TEXT_AUTO_PUNCTUATE_VALIDATOR); + VALIDATORS.put(TEXT_SHOW_PASSWORD, TEXT_SHOW_PASSWORD_VALIDATOR); + VALIDATORS.put(AUTO_TIME, AUTO_TIME_VALIDATOR); + VALIDATORS.put(AUTO_TIME_ZONE, AUTO_TIME_ZONE_VALIDATOR); + VALIDATORS.put(SHOW_GTALK_SERVICE_STATUS, SHOW_GTALK_SERVICE_STATUS_VALIDATOR); + VALIDATORS.put(WALLPAPER_ACTIVITY, WALLPAPER_ACTIVITY_VALIDATOR); + VALIDATORS.put(TIME_12_24, TIME_12_24_VALIDATOR); + VALIDATORS.put(DATE_FORMAT, DATE_FORMAT_VALIDATOR); + VALIDATORS.put(SETUP_WIZARD_HAS_RUN, SETUP_WIZARD_HAS_RUN_VALIDATOR); + VALIDATORS.put(ACCELEROMETER_ROTATION, ACCELEROMETER_ROTATION_VALIDATOR); + VALIDATORS.put(USER_ROTATION, USER_ROTATION_VALIDATOR); + VALIDATORS.put(DTMF_TONE_WHEN_DIALING, DTMF_TONE_WHEN_DIALING_VALIDATOR); + VALIDATORS.put(SOUND_EFFECTS_ENABLED, SOUND_EFFECTS_ENABLED_VALIDATOR); + VALIDATORS.put(HAPTIC_FEEDBACK_ENABLED, HAPTIC_FEEDBACK_ENABLED_VALIDATOR); + VALIDATORS.put(POWER_SOUNDS_ENABLED, POWER_SOUNDS_ENABLED_VALIDATOR); + VALIDATORS.put(DOCK_SOUNDS_ENABLED, DOCK_SOUNDS_ENABLED_VALIDATOR); + VALIDATORS.put(SHOW_WEB_SUGGESTIONS, SHOW_WEB_SUGGESTIONS_VALIDATOR); + VALIDATORS.put(WIFI_USE_STATIC_IP, WIFI_USE_STATIC_IP_VALIDATOR); + VALIDATORS.put(END_BUTTON_BEHAVIOR, END_BUTTON_BEHAVIOR_VALIDATOR); + VALIDATORS.put(ADVANCED_SETTINGS, ADVANCED_SETTINGS_VALIDATOR); + VALIDATORS.put(SCREEN_AUTO_BRIGHTNESS_ADJ, SCREEN_AUTO_BRIGHTNESS_ADJ_VALIDATOR); + VALIDATORS.put(VIBRATE_INPUT_DEVICES, VIBRATE_INPUT_DEVICES_VALIDATOR); + VALIDATORS.put(MASTER_MONO, MASTER_MONO_VALIDATOR); + VALIDATORS.put(NOTIFICATIONS_USE_RING_VOLUME, NOTIFICATIONS_USE_RING_VOLUME_VALIDATOR); + VALIDATORS.put(VIBRATE_IN_SILENT, VIBRATE_IN_SILENT_VALIDATOR); + VALIDATORS.put(MEDIA_BUTTON_RECEIVER, MEDIA_BUTTON_RECEIVER_VALIDATOR); + VALIDATORS.put(HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, + HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY_VALIDATOR); + VALIDATORS.put(VIBRATE_WHEN_RINGING, VIBRATE_WHEN_RINGING_VALIDATOR); + VALIDATORS.put(DTMF_TONE_TYPE_WHEN_DIALING, DTMF_TONE_TYPE_WHEN_DIALING_VALIDATOR); + VALIDATORS.put(HEARING_AID, HEARING_AID_VALIDATOR); + VALIDATORS.put(TTY_MODE, TTY_MODE_VALIDATOR); + VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, NOTIFICATION_LIGHT_PULSE_VALIDATOR); + VALIDATORS.put(POINTER_LOCATION, POINTER_LOCATION_VALIDATOR); + VALIDATORS.put(SHOW_TOUCHES, SHOW_TOUCHES_VALIDATOR); + VALIDATORS.put(WINDOW_ORIENTATION_LISTENER_LOG, + WINDOW_ORIENTATION_LISTENER_LOG_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_SOUNDS_ENABLED, LOCKSCREEN_SOUNDS_ENABLED_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_DISABLED, LOCKSCREEN_DISABLED_VALIDATOR); + VALIDATORS.put(SIP_RECEIVE_CALLS, SIP_RECEIVE_CALLS_VALIDATOR); + VALIDATORS.put(SIP_CALL_OPTIONS, SIP_CALL_OPTIONS_VALIDATOR); + VALIDATORS.put(SIP_ALWAYS, SIP_ALWAYS_VALIDATOR); + VALIDATORS.put(SIP_ADDRESS_ONLY, SIP_ADDRESS_ONLY_VALIDATOR); + VALIDATORS.put(SIP_ASK_ME_EACH_TIME, SIP_ASK_ME_EACH_TIME_VALIDATOR); + VALIDATORS.put(POINTER_SPEED, POINTER_SPEED_VALIDATOR); + VALIDATORS.put(LOCK_TO_APP_ENABLED, LOCK_TO_APP_ENABLED_VALIDATOR); + VALIDATORS.put(EGG_MODE, EGG_MODE_VALIDATOR); + VALIDATORS.put(WIFI_STATIC_IP, WIFI_STATIC_IP_VALIDATOR); + VALIDATORS.put(WIFI_STATIC_GATEWAY, WIFI_STATIC_GATEWAY_VALIDATOR); + VALIDATORS.put(WIFI_STATIC_NETMASK, WIFI_STATIC_NETMASK_VALIDATOR); + VALIDATORS.put(WIFI_STATIC_DNS1, WIFI_STATIC_DNS1_VALIDATOR); + VALIDATORS.put(WIFI_STATIC_DNS2, WIFI_STATIC_DNS2_VALIDATOR); + VALIDATORS.put(SHOW_BATTERY_PERCENT, SHOW_BATTERY_PERCENT_VALIDATOR); + VALIDATORS.put(ACCELEROMETER_ROTATION_ANGLES, ACCELEROMETER_ROTATION_ANGLES_VALIDATOR); + VALIDATORS.put(ANIM_TILE_STYLE, ANIM_TILE_STYLE_VALIDATOR); + VALIDATORS.put(ANIM_TILE_DURATION, ANIM_TILE_DURATION_VALIDATOR); + VALIDATORS.put(ANIM_TILE_INTERPOLATOR, ANIM_TILE_INTERPOLATOR_VALIDATOR); + VALIDATORS.put(ANSWER_VOLUME_BUTTON_BEHAVIOR_ANSWER, ANSWER_VOLUME_BUTTON_BEHAVIOR_ANSWER_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_ENABLED, BATTERY_LIGHT_ENABLED_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_ALLOW_ON_DND, BATTERY_LIGHT_ALLOW_ON_DND_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_LOW_BLINKING, BATTERY_LIGHT_LOW_BLINKING_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_LOW_COLOR, BATTERY_LIGHT_LOW_COLOR_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_MEDIUM_COLOR, BATTERY_LIGHT_MEDIUM_COLOR_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_FULL_COLOR, BATTERY_LIGHT_FULL_COLOR_VALIDATOR); + VALIDATORS.put(BATTERY_LIGHT_REALLYFULL_COLOR, BATTERY_LIGHT_REALLYFULL_COLOR_VALIDATOR); + VALIDATORS.put(BOTTOM_GESTURE_TRIGGER_TIMEOUT, BOTTOM_GESTURE_TRIGGER_TIMEOUT_VALIDATOR); + VALIDATORS.put(BOTTOM_GESTURE_SWIPE_START, BOTTOM_GESTURE_SWIPE_START_VALIDATOR); + VALIDATORS.put(BOTTOM_GESTURE_SWIPE_LIMIT, BOTTOM_GESTURE_SWIPE_LIMIT_VALIDATOR); + VALIDATORS.put(BOTTOM_GESTURE_FEEDBACK_DURATION, BOTTOM_GESTURE_FEEDBACK_DURATION_VALIDATOR); + VALIDATORS.put(CUSTOM_CARRIER_LABEL, CUSTOM_CARRIER_LABEL_VALIDATOR); + VALIDATORS.put(DOUBLE_TAP_SLEEP_GESTURE, DOUBLE_TAP_SLEEP_GESTURE_VALIDATOR); + VALIDATORS.put(DOUBLE_TAP_SLEEP_ANYWHERE, DOUBLE_TAP_SLEEP_ANYWHERE_VALIDATOR); + VALIDATORS.put(FINGERPRINT_SUCCESS_VIB, FINGERPRINT_SUCCESS_VIB_VALIDATOR); + VALIDATORS.put(FORCE_AMBIENT_FOR_MEDIA, FORCE_AMBIENT_FOR_MEDIA_VALIDATOR); + VALIDATORS.put(FULL_GESTURE_NAVBAR, FULL_GESTURE_NAVBAR_VALIDATOR); + VALIDATORS.put(FULL_GESTURE_NAVBAR_DT2S, FULL_GESTURE_NAVBAR_DT2S_VALIDATOR); + VALIDATORS.put(HEADS_UP_TIMEOUT, HEADS_UP_TIMEOUT_VALIDATOR); + VALIDATORS.put(HEADS_UP_NOTIFICATION_SNOOZE, HEADS_UP_NOTIFICATION_SNOOZE_VALIDATOR); + VALIDATORS.put(INCREASING_RING, INCREASING_RING_VALIDATOR); + VALIDATORS.put(INCREASING_RING_START_VOLUME, INCREASING_RING_START_VOLUME_VALIDATOR); + VALIDATORS.put(INCREASING_RING_RAMP_UP_TIME, INCREASING_RING_RAMP_UP_TIME_VALIDATOR); + VALIDATORS.put(LOCK_QS_DISABLED, LOCK_QS_DISABLED_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_CLOCK, LOCKSCREEN_CLOCK_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_CLOCK_SELECTION, LOCKSCREEN_CLOCK_SELECTION_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_CHARGING_CURRENT, LOCKSCREEN_CHARGING_CURRENT_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_INFO, LOCKSCREEN_INFO_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_MEDIA_METADATA, LOCKSCREEN_MEDIA_METADATA_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_PIN_SCRAMBLE_LAYOUT, LOCKSCREEN_PIN_SCRAMBLE_LAYOUT_VALIDATOR); + VALIDATORS.put(MUTE_ANNOYING_NOTIFICATIONS_THRESHOLD, MUTE_ANNOYING_NOTIFICATIONS_THRESHOLD_VALIDATOR); + VALIDATORS.put(NETWORK_TRAFFIC_AUTOHIDE, NETWORK_TRAFFIC_AUTOHIDE_VALIDATOR); + VALIDATORS.put(NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD, NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD_VALIDATOR); + VALIDATORS.put(NETWORK_TRAFFIC_HIDEARROW, NETWORK_TRAFFIC_HIDEARROW_VALIDATOR); + VALIDATORS.put(NETWORK_TRAFFIC_STATE, NETWORK_TRAFFIC_STATE_VALIDATOR); + VALIDATORS.put(NOTIFICATION_SOUND_VIB_SCREEN_ON, NOTIFICATION_SOUND_VIB_SCREEN_ON_VALIDATOR); + VALIDATORS.put(POWERMENU_ADVANCED_REBOOT, POWERMENU_ADVANCED_REBOOT_VALIDATOR); + VALIDATORS.put(POWERMENU_AIRPLANE, POWERMENU_AIRPLANE_VALIDATOR); + VALIDATORS.put(POWERMENU_REBOOT, POWERMENU_REBOOT_VALIDATOR); + VALIDATORS.put(POWERMENU_SCREENSHOT, POWERMENU_SCREENSHOT_VALIDATOR); + VALIDATORS.put(QS_LAYOUT_ROWS, QS_LAYOUT_ROWS_VALIDATOR); + VALIDATORS.put(QS_LAYOUT_ROWS_LANDSCAPE, QS_LAYOUT_ROWS_LANDSCAPE_VALIDATOR); + VALIDATORS.put(QS_LAYOUT_COLUMNS_LANDSCAPE, QS_LAYOUT_COLUMNS_LANDSCAPE_VALIDATOR); + VALIDATORS.put(QS_LAYOUT_COLUMNS, QS_LAYOUT_COLUMNS_VALIDATOR); + VALIDATORS.put(QS_QUICKBAR_COLUMNS, QS_QUICKBAR_COLUMNS_VALIDATOR); + VALIDATORS.put(QS_SMART_PULLDOWN, QS_SMART_PULLDOWN_VALIDATOR); + VALIDATORS.put(QS_TILE_HIDE_TITLE, QS_TILE_HIDE_TITLE_VALIDATOR); + VALIDATORS.put(RECENTS_CLEAR_ALL_LOCATION, RECENTS_CLEAR_ALL_LOCATION_VALIDATOR); + VALIDATORS.put(RECENTS_COMPONENT,RECENTS_COMPONENT_VALIDATOR); + VALIDATORS.put(SCREENSHOT_DEFAULT_MODE, SCREENSHOT_DEFAULT_MODE_VALIDATOR); + VALIDATORS.put(SCREENRECORD_QUALITY_MODE, SCREENRECORD_QUALITY_MODE_VALIDATOR); + VALIDATORS.put(SCREENSHOT_SHUTTER_SOUND, SCREENSHOT_SHUTTER_SOUND_VALIDATOR); + VALIDATORS.put(SHOW_CLEAR_ALL_RECENTS, SHOW_CLEAR_ALL_RECENTS_VALIDATOR); + VALIDATORS.put(SHOW_FOURG, SHOW_FOURG_VALIDATOR); + VALIDATORS.put(SHOW_VOLTE_ICON, SHOW_VOLTE_ICON_VALIDATOR); + VALIDATORS.put(STATUS_BAR_BRIGHTNESS_CONTROL, STATUS_BAR_BRIGHTNESS_CONTROL_VALIDATOR); + VALIDATORS.put(STATUS_BAR_QUICK_QS_PULLDOWN, STATUS_BAR_QUICK_QS_PULLDOWN_VALIDATOR); + VALIDATORS.put(STATUS_BAR_SHOW_CARRIER, STATUS_BAR_SHOW_CARRIER_VALIDATOR); + VALIDATORS.put(STATUS_BAR_CLOCK, STATUS_BAR_CLOCK_VALIDATOR); + VALIDATORS.put(STATUS_BAR_CLOCK_SECONDS, STATUS_BAR_CLOCK_SECONDS_VALIDATOR); + VALIDATORS.put(STATUS_BAR_SHOW_TICKER, STATUS_BAR_SHOW_TICKER_VALIDATOR); + VALIDATORS.put(STATUS_BAR_TICKER_ANIMATION_MODE, STATUS_BAR_TICKER_ANIMATION_MODE_VALIDATOR); + VALIDATORS.put(STATUS_BAR_TICKER_TICK_DURATION, STATUS_BAR_TICKER_TICK_DURATION_VALIDATOR); + VALIDATORS.put(STATUSBAR_CLOCK_AM_PM_STYLE, STATUSBAR_CLOCK_AM_PM_STYLE_VALIDATOR); + VALIDATORS.put(STATUSBAR_CLOCK_DATE_DISPLAY, STATUSBAR_CLOCK_DATE_DISPLAY_VALIDATOR); + VALIDATORS.put(STATUSBAR_CLOCK_DATE_STYLE, STATUSBAR_CLOCK_DATE_STYLE_VALIDATOR); + VALIDATORS.put(STATUSBAR_CLOCK_DATE_FORMAT, STATUSBAR_CLOCK_DATE_FORMAT_VALIDATOR); + VALIDATORS.put(STATUSBAR_CLOCK_DATE_POSITION, STATUSBAR_CLOCK_DATE_POSITION_VALIDATOR); + VALIDATORS.put(STATUSBAR_CLOCK_STYLE, STATUSBAR_CLOCK_STYLE_VALIDATOR); + VALIDATORS.put(STATUSBAR_HIDE_NOTCH, STATUSBAR_HIDE_NOTCH_VALIDATOR); + VALIDATORS.put(SWAP_VOLUME_BUTTONS, SWAP_VOLUME_BUTTONS_VALIDATOR); + VALIDATORS.put(TOAST_ICON, TOAST_ICON_VALIDATOR); + VALIDATORS.put(THREE_FINGER_GESTURE, THREE_FINGER_GESTURE_VALIDATOR); + VALIDATORS.put(USE_BLACKAF_THEME, USE_BLACKAF_THEME_VALIDATOR); + VALIDATORS.put(USE_BOTTOM_GESTURE_NAVIGATION, USE_BOTTOM_GESTURE_NAVIGATION_VALIDATOR); + VALIDATORS.put(USE_OLD_MOBILETYPE, USE_OLD_MOBILETYPE_VALIDATOR); + VALIDATORS.put(VIBRATE_ON_CONNECT, VIBRATE_ON_CONNECT_VALIDATOR); + VALIDATORS.put(VIBRATE_ON_CALLWAITING, VIBRATE_ON_CALLWAITING_VALIDATOR); + VALIDATORS.put(VIBRATE_ON_DISCONNECT, VIBRATE_ON_DISCONNECT_VALIDATOR); + VALIDATORS.put(VIBRATION_ON_CHARGE_STATE_CHANGED, VIBRATION_ON_CHARGE_STATE_CHANGED_VALIDATOR); + VALIDATORS.put(VOLUME_BUTTON_MUSIC_CONTROL, VOLUME_BUTTON_MUSIC_CONTROL_VALIDATOR); + VALIDATORS.put(VOLUME_KEYS_CONTROL_RING_TONE,VOLUME_KEYS_CONTROL_RING_TONE_VALIDATOR); + VALIDATORS.put(VOLUME_KEY_CURSOR_CONTROL, VOLUME_KEY_CURSOR_CONTROL_VALIDATOR); + VALIDATORS.put(VOLUME_ROCKER_WAKE, VOLUME_ROCKER_WAKE_VALIDATOR); + VALIDATORS.put(WAKE_WHEN_PLUGGED_OR_UNPLUGGED, WAKE_WHEN_PLUGGED_OR_UNPLUGGED_VALIDATOR); + VALIDATORS.put(RECENTS_COMPONENT,RECENTS_COMPONENT_VALIDATOR); + VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR); + VALIDATORS.put(DOZE_ON_CHARGE, DOZE_ON_CHARGE_VALIDATOR); + VALIDATORS.put(STATUS_BAR_LOGO, STATUS_BAR_LOGO_VALIDATOR); + VALIDATORS.put(DISPLAY_MODE, DISPLAY_MODE_VALIDATOR); + VALIDATORS.put(QS_PANEL_BG_ALPHA, QS_PANEL_BG_ALPHA_VALIDATOR); + } + + /** + * These entries are considered common between the personal and the managed profile, + * since the managed profile doesn't get to change them. + */ + private static final Set CLONE_TO_MANAGED_PROFILE = new ArraySet<>(); + static { + CLONE_TO_MANAGED_PROFILE.add(DATE_FORMAT); + CLONE_TO_MANAGED_PROFILE.add(HAPTIC_FEEDBACK_ENABLED); + CLONE_TO_MANAGED_PROFILE.add(SOUND_EFFECTS_ENABLED); + CLONE_TO_MANAGED_PROFILE.add(TEXT_SHOW_PASSWORD); + CLONE_TO_MANAGED_PROFILE.add(TIME_12_24); + } + + /** @hide */ + public static void getCloneToManagedProfileSettings(Set outKeySet) { + outKeySet.addAll(CLONE_TO_MANAGED_PROFILE); + } + + /** + * These entries should be cloned from this profile's parent only if the dependency's + * value is true ("1") + * + * Note: the dependencies must be Secure settings + * + * @hide + */ + public static final Map CLONE_FROM_PARENT_ON_VALUE = new ArrayMap<>(); + static { + CLONE_FROM_PARENT_ON_VALUE.put(RINGTONE, Secure.SYNC_PARENT_SOUNDS); + CLONE_FROM_PARENT_ON_VALUE.put(RINGTONE2, Secure.SYNC_PARENT_SOUNDS); + CLONE_FROM_PARENT_ON_VALUE.put(NOTIFICATION_SOUND, Secure.SYNC_PARENT_SOUNDS); + CLONE_FROM_PARENT_ON_VALUE.put(ALARM_ALERT, Secure.SYNC_PARENT_SOUNDS); + } + + /** @hide */ + public static void getCloneFromParentOnValueSettings(Map outMap) { + outMap.putAll(CLONE_FROM_PARENT_ON_VALUE); + } + + /** + * System settings which can be accessed by instant apps. + * @hide + */ + public static final Set INSTANT_APP_SETTINGS = new ArraySet<>(); + static { + INSTANT_APP_SETTINGS.add(TEXT_AUTO_REPLACE); + INSTANT_APP_SETTINGS.add(TEXT_AUTO_CAPS); + INSTANT_APP_SETTINGS.add(TEXT_AUTO_PUNCTUATE); + INSTANT_APP_SETTINGS.add(TEXT_SHOW_PASSWORD); + INSTANT_APP_SETTINGS.add(DATE_FORMAT); + INSTANT_APP_SETTINGS.add(FONT_SCALE); + INSTANT_APP_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED); + INSTANT_APP_SETTINGS.add(TIME_12_24); + INSTANT_APP_SETTINGS.add(SOUND_EFFECTS_ENABLED); + INSTANT_APP_SETTINGS.add(ACCELEROMETER_ROTATION); + } + + /** + * When to use Wi-Fi calling + * + * @see android.telephony.TelephonyManager.WifiCallingChoices + * @hide + */ + public static final String WHEN_TO_MAKE_WIFI_CALLS = "when_to_make_wifi_calls"; + + // Settings moved to Settings.Secure + + /** + * @deprecated Use {@link android.provider.Settings.Global#ADB_ENABLED} + * instead + */ + @Deprecated + public static final String ADB_ENABLED = Global.ADB_ENABLED; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#ANDROID_ID} instead + */ + @Deprecated + public static final String ANDROID_ID = Secure.ANDROID_ID; + + /** + * @deprecated Use {@link android.provider.Settings.Global#BLUETOOTH_ON} instead + */ + @Deprecated + public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON; + + private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead + */ + @Deprecated + public static final String DATA_ROAMING = Global.DATA_ROAMING; + + /** + * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead + */ + @Deprecated + public static final String DEVICE_PROVISIONED = Global.DEVICE_PROVISIONED; + + /** + * @deprecated Use {@link android.provider.Settings.Global#HTTP_PROXY} instead + */ + @Deprecated + public static final String HTTP_PROXY = Global.HTTP_PROXY; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS} instead + */ + @Deprecated + public static final String INSTALL_NON_MARKET_APPS = Secure.INSTALL_NON_MARKET_APPS; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#LOCATION_PROVIDERS_ALLOWED} + * instead + */ + @Deprecated + public static final String LOCATION_PROVIDERS_ALLOWED = Secure.LOCATION_PROVIDERS_ALLOWED; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#LOGGING_ID} instead + */ + @Deprecated + public static final String LOGGING_ID = Secure.LOGGING_ID; + + /** + * @deprecated Use {@link android.provider.Settings.Global#NETWORK_PREFERENCE} instead + */ + @Deprecated + public static final String NETWORK_PREFERENCE = Global.NETWORK_PREFERENCE; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#PARENTAL_CONTROL_ENABLED} + * instead + */ + @Deprecated + public static final String PARENTAL_CONTROL_ENABLED = Secure.PARENTAL_CONTROL_ENABLED; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#PARENTAL_CONTROL_LAST_UPDATE} + * instead + */ + @Deprecated + public static final String PARENTAL_CONTROL_LAST_UPDATE = Secure.PARENTAL_CONTROL_LAST_UPDATE; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#PARENTAL_CONTROL_REDIRECT_URL} + * instead + */ + @Deprecated + public static final String PARENTAL_CONTROL_REDIRECT_URL = + Secure.PARENTAL_CONTROL_REDIRECT_URL; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#SETTINGS_CLASSNAME} instead + */ + @Deprecated + public static final String SETTINGS_CLASSNAME = Secure.SETTINGS_CLASSNAME; + + /** + * @deprecated Use {@link android.provider.Settings.Global#USB_MASS_STORAGE_ENABLED} instead + */ + @Deprecated + public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED; + + private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead + */ + @Deprecated + public static final String USE_GOOGLE_MAIL = Global.USE_GOOGLE_MAIL; + + /** + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_MAX_DHCP_RETRY_COUNT} instead + */ + @Deprecated + public static final String WIFI_MAX_DHCP_RETRY_COUNT = Global.WIFI_MAX_DHCP_RETRY_COUNT; + + /** + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS} instead + */ + @Deprecated + public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = + Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS; + + /** + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON} instead + */ + @Deprecated + public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = + Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; + + private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} instead + */ + @Deprecated + public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = + Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY; + + private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; + + /** + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT} + * instead + */ + @Deprecated + public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = Global.WIFI_NUM_OPEN_NETWORKS_KEPT; + + private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; + + /** + * @deprecated Use {@link android.provider.Settings.Global#WIFI_ON} instead + */ + @Deprecated + public static final String WIFI_ON = Global.WIFI_ON; + + /** + * @deprecated Use + * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE} + * instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = + Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_AP_COUNT} instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_AP_COUNT = Secure.WIFI_WATCHDOG_AP_COUNT; + + /** + * @deprecated Use + * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS} instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = + Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS; + + /** + * @deprecated Use + * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED} instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = + Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED; + + /** + * @deprecated Use + * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS} + * instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = + Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS; + + /** + * @deprecated Use + * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = + Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_MAX_AP_CHECKS} + * instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = Secure.WIFI_WATCHDOG_MAX_AP_CHECKS; + + /** + * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_ON = Global.WIFI_WATCHDOG_ON; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_PING_COUNT} instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_PING_COUNT = Secure.WIFI_WATCHDOG_PING_COUNT; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_PING_DELAY_MS} + * instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_PING_DELAY_MS = Secure.WIFI_WATCHDOG_PING_DELAY_MS; + + /** + * @deprecated Use {@link android.provider.Settings.Secure#WIFI_WATCHDOG_PING_TIMEOUT_MS} + * instead + */ + @Deprecated + public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = + Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS; + + /** + * Checks if the specified app can modify system settings. As of API + * level 23, an app cannot modify system settings unless it declares the + * {@link android.Manifest.permission#WRITE_SETTINGS} + * permission in its manifest, and the user specifically grants + * the app this capability. To prompt the user to grant this approval, + * the app must send an intent with the action {@link + * android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}, which causes + * the system to display a permission management screen. + * + * @param context App context. + * @return true if the calling app can write to system settings, false otherwise + */ + public static boolean canWrite(Context context) { + return isCallingPackageAllowedToWriteSettings(context, Process.myUid(), + context.getOpPackageName(), false); + } + } + + /** + * Secure system settings, containing system preferences that applications + * can read but are not allowed to write. These are for preferences that + * the user must explicitly modify through the system UI or specialized + * APIs for those values, not modified directly by applications. + */ + public static final class Secure extends NameValueTable { + // NOTE: If you add new settings here, be sure to add them to + // com.android.providers.settings.SettingsProtoDumpUtil#dumpProtoSecureSettingsLocked. + + /** + * The content:// style URL for this table + */ + public static final Uri CONTENT_URI = + Uri.parse("content://" + AUTHORITY + "/secure"); + + private static final ContentProviderHolder sProviderHolder = + new ContentProviderHolder(CONTENT_URI); + + // Populated lazily, guarded by class object: + private static final NameValueCache sNameValueCache = new NameValueCache( + CONTENT_URI, + CALL_METHOD_GET_SECURE, + CALL_METHOD_PUT_SECURE, + sProviderHolder); + + private static ILockSettings sLockSettings = null; + + private static boolean sIsSystemProcess; + private static final HashSet MOVED_TO_LOCK_SETTINGS; + private static final HashSet MOVED_TO_GLOBAL; + static { + MOVED_TO_LOCK_SETTINGS = new HashSet<>(3); + MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_ENABLED); + MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_VISIBLE); + MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED); + + MOVED_TO_GLOBAL = new HashSet<>(); + MOVED_TO_GLOBAL.add(Settings.Global.ADB_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.ASSISTED_GPS_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.BLUETOOTH_ON); + MOVED_TO_GLOBAL.add(Settings.Global.BUGREPORT_IN_POWER_MENU); + MOVED_TO_GLOBAL.add(Settings.Global.CDMA_CELL_BROADCAST_SMS); + MOVED_TO_GLOBAL.add(Settings.Global.CDMA_ROAMING_MODE); + MOVED_TO_GLOBAL.add(Settings.Global.CDMA_SUBSCRIPTION_MODE); + MOVED_TO_GLOBAL.add(Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE); + MOVED_TO_GLOBAL.add(Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI); + MOVED_TO_GLOBAL.add(Settings.Global.DATA_ROAMING); + MOVED_TO_GLOBAL.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.DEVICE_PROVISIONED); + MOVED_TO_GLOBAL.add(Settings.Global.DISPLAY_SIZE_FORCED); + MOVED_TO_GLOBAL.add(Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE); + MOVED_TO_GLOBAL.add(Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE); + MOVED_TO_GLOBAL.add(Settings.Global.MOBILE_DATA); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_BUCKET_DURATION); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_DELETE_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_PERSIST_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_DEV_ROTATE_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_POLL_INTERVAL); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_SAMPLE_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_BUCKET_DURATION); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_DELETE_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_PERSIST_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_ROTATE_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_DELETE_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE); + MOVED_TO_GLOBAL.add(Settings.Global.NETWORK_PREFERENCE); + MOVED_TO_GLOBAL.add(Settings.Global.NITZ_UPDATE_DIFF); + MOVED_TO_GLOBAL.add(Settings.Global.NITZ_UPDATE_SPACING); + MOVED_TO_GLOBAL.add(Settings.Global.NTP_SERVER); + MOVED_TO_GLOBAL.add(Settings.Global.NTP_TIMEOUT); + MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_ERROR_POLL_COUNT); + MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS); + MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT); + MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS); + MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT); + MOVED_TO_GLOBAL.add(Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL); + MOVED_TO_GLOBAL.add(Settings.Global.SETUP_PREPAID_DETECTION_REDIR_HOST); + MOVED_TO_GLOBAL.add(Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL); + MOVED_TO_GLOBAL.add(Settings.Global.TETHER_DUN_APN); + MOVED_TO_GLOBAL.add(Settings.Global.TETHER_DUN_REQUIRED); + MOVED_TO_GLOBAL.add(Settings.Global.TETHER_SUPPORTED); + MOVED_TO_GLOBAL.add(Settings.Global.USB_MASS_STORAGE_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.USE_GOOGLE_MAIL); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_COUNTRY_CODE); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_FREQUENCY_BAND); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_IDLE_MS); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NUM_OPEN_NETWORKS_KEPT); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_ON); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_P2P_DEVICE_NAME); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SAVED_STATE); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_ENHANCED_AUTO_JOIN); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_NETWORK_SHOW_RSSI); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_ON); + MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON); + MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_ENABLE); + MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_TIMEOUT); + MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE); + MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS); + MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS); + MOVED_TO_GLOBAL.add(Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS); + MOVED_TO_GLOBAL.add(Settings.Global.WTF_IS_FATAL); + MOVED_TO_GLOBAL.add(Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD); + MOVED_TO_GLOBAL.add(Settings.Global.BATTERY_DISCHARGE_THRESHOLD); + MOVED_TO_GLOBAL.add(Settings.Global.SEND_ACTION_APP_ERROR); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_AGE_SECONDS); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_MAX_FILES); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_QUOTA_KB); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_QUOTA_PERCENT); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_RESERVE_PERCENT); + MOVED_TO_GLOBAL.add(Settings.Global.DROPBOX_TAG_PREFIX); + MOVED_TO_GLOBAL.add(Settings.Global.ERROR_LOGCAT_PREFIX); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL); + MOVED_TO_GLOBAL.add(Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES); + MOVED_TO_GLOBAL.add(Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS); + MOVED_TO_GLOBAL.add(Settings.Global.CONNECTIVITY_CHANGE_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED); + MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_SERVER); + MOVED_TO_GLOBAL.add(Settings.Global.NSD_ON); + MOVED_TO_GLOBAL.add(Settings.Global.SET_INSTALL_LOCATION); + MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_INSTALL_LOCATION); + MOVED_TO_GLOBAL.add(Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY); + MOVED_TO_GLOBAL.add(Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT); + MOVED_TO_GLOBAL.add(Settings.Global.HTTP_PROXY); + MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_HOST); + MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_PORT); + MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST); + MOVED_TO_GLOBAL.add(Settings.Global.SET_GLOBAL_HTTP_PROXY); + MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_DNS_SERVER); + MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_NETWORK_MODE); + MOVED_TO_GLOBAL.add(Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY); + } + + /** @hide */ + public static void getMovedToGlobalSettings(Set outKeySet) { + outKeySet.addAll(MOVED_TO_GLOBAL); + } + + /** @hide */ + public static void clearProviderForTest() { + sProviderHolder.clearProviderForTest(); + sNameValueCache.clearGenerationTrackerForTest(); + } + + /** + * Look up a name in the database. + * @param resolver to access the database with + * @param name to look up in the table + * @return the corresponding value, or null if not present + */ + public static String getString(ContentResolver resolver, String name) { + return getStringForUser(resolver, name, resolver.getUserId()); + } + + /** @hide */ + public static String getStringForUser(ContentResolver resolver, String name, + int userHandle) { + if (MOVED_TO_GLOBAL.contains(name)) { + Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" + + " to android.provider.Settings.Global."); + return Global.getStringForUser(resolver, name, userHandle); + } + + if (MOVED_TO_LOCK_SETTINGS.contains(name)) { + synchronized (Secure.class) { + if (sLockSettings == null) { + sLockSettings = ILockSettings.Stub.asInterface( + (IBinder) ServiceManager.getService("lock_settings")); + sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID; + } + } + if (sLockSettings != null && !sIsSystemProcess) { + // No context; use the ActivityThread's context as an approximation for + // determining the target API level. + Application application = ActivityThread.currentApplication(); + + boolean isPreMnc = application != null + && application.getApplicationInfo() != null + && application.getApplicationInfo().targetSdkVersion + <= VERSION_CODES.LOLLIPOP_MR1; + if (isPreMnc) { + try { + return sLockSettings.getString(name, "0", userHandle); + } catch (RemoteException re) { + // Fall through + } + } else { + throw new SecurityException("Settings.Secure." + name + + " is deprecated and no longer accessible." + + " See API documentation for potential replacements."); + } + } + } + + return sNameValueCache.getStringForUser(resolver, name, userHandle); + } + + /** + * Store a name/value pair into the database. + * @param resolver to access the database with + * @param name to store + * @param value to associate with the name + * @return true if the value was set, false on database errors + */ + public static boolean putString(ContentResolver resolver, String name, String value) { + return putStringForUser(resolver, name, value, resolver.getUserId()); + } + + /** @hide */ + public static boolean putStringForUser(ContentResolver resolver, String name, String value, + int userHandle) { + return putStringForUser(resolver, name, value, null, false, userHandle); + } + + /** @hide */ + public static boolean putStringForUser(@NonNull ContentResolver resolver, + @NonNull String name, @Nullable String value, @Nullable String tag, + boolean makeDefault, @UserIdInt int userHandle) { + if (LOCATION_MODE.equals(name)) { + // Map LOCATION_MODE to underlying location provider storage API + return setLocationModeForUser(resolver, Integer.parseInt(value), userHandle); + } + if (MOVED_TO_GLOBAL.contains(name)) { + Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" + + " to android.provider.Settings.Global"); + return Global.putStringForUser(resolver, name, value, + tag, makeDefault, userHandle); + } + return sNameValueCache.putStringForUser(resolver, name, value, tag, + makeDefault, userHandle); + } + + /** + * Store a name/value pair into the database. + *

+ * The method takes an optional tag to associate with the setting + * which can be used to clear only settings made by your package and + * associated with this tag by passing the tag to {@link + * #resetToDefaults(ContentResolver, String)}. Anyone can override + * the current tag. Also if another package changes the setting + * then the tag will be set to the one specified in the set call + * which can be null. Also any of the settings setters that do not + * take a tag as an argument effectively clears the tag. + *

+ * For example, if you set settings A and B with tags T1 and T2 and + * another app changes setting A (potentially to the same value), it * can assign to it a tag T3 (note that now the package that changed * the setting is not yours). Now if you reset your changes for T1 and * T2 only setting B will be reset and A not (as it was changed by @@ -4964,2148 +6477,2721 @@ public static boolean putStringForUser(@NonNull ContentResolver resolver, * be set as the default. *

* - * @param resolver to access the database with. - * @param name to store. - * @param value to associate with the name. - * @param tag to associate with the setting. - * @param makeDefault whether to make the value the default one. - * @return true if the value was set, false on database errors. + * @param resolver to access the database with. + * @param name to store. + * @param value to associate with the name. + * @param tag to associate with the setting. + * @param makeDefault whether to make the value the default one. + * @return true if the value was set, false on database errors. + * + * @see #resetToDefaults(ContentResolver, String) + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public static boolean putString(@NonNull ContentResolver resolver, + @NonNull String name, @Nullable String value, @Nullable String tag, + boolean makeDefault) { + return putStringForUser(resolver, name, value, tag, makeDefault, + resolver.getUserId()); + } + + /** + * Reset the settings to their defaults. This would reset only + * settings set by the caller's package. Think of it of a way to undo your own + * changes to the global settings. Passing in the optional tag will reset only + * settings changed by your package and associated with this tag. + * + * @param resolver Handle to the content resolver. + * @param tag Optional tag which should be associated with the settings to reset. + * + * @see #putString(ContentResolver, String, String, String, boolean) + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public static void resetToDefaults(@NonNull ContentResolver resolver, + @Nullable String tag) { + resetToDefaultsAsUser(resolver, tag, RESET_MODE_PACKAGE_DEFAULTS, + resolver.getUserId()); + } + + /** + * + * Reset the settings to their defaults for a given user with a specific mode. The + * optional tag argument is valid only for {@link #RESET_MODE_PACKAGE_DEFAULTS} + * allowing resetting the settings made by a package and associated with the tag. + * + * @param resolver Handle to the content resolver. + * @param tag Optional tag which should be associated with the settings to reset. + * @param mode The reset mode. + * @param userHandle The user for which to reset to defaults. + * + * @see #RESET_MODE_PACKAGE_DEFAULTS + * @see #RESET_MODE_UNTRUSTED_DEFAULTS + * @see #RESET_MODE_UNTRUSTED_CHANGES + * @see #RESET_MODE_TRUSTED_DEFAULTS + * + * @hide + */ + public static void resetToDefaultsAsUser(@NonNull ContentResolver resolver, + @Nullable String tag, @ResetMode int mode, @IntRange(from = 0) int userHandle) { + try { + Bundle arg = new Bundle(); + arg.putInt(CALL_METHOD_USER_KEY, userHandle); + if (tag != null) { + arg.putString(CALL_METHOD_TAG_KEY, tag); + } + arg.putInt(CALL_METHOD_RESET_MODE_KEY, mode); + IContentProvider cp = sProviderHolder.getProvider(resolver); + cp.call(resolver.getPackageName(), CALL_METHOD_RESET_SECURE, null, arg); + } catch (RemoteException e) { + Log.w(TAG, "Can't reset do defaults for " + CONTENT_URI, e); + } + } + + /** + * Construct the content URI for a particular name/value pair, + * useful for monitoring changes with a ContentObserver. + * @param name to look up in the table + * @return the corresponding content URI, or null if not present + */ + public static Uri getUriFor(String name) { + if (MOVED_TO_GLOBAL.contains(name)) { + Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" + + " to android.provider.Settings.Global, returning global URI."); + return Global.getUriFor(Global.CONTENT_URI, name); + } + return getUriFor(CONTENT_URI, name); + } + + /** + * Convenience function for retrieving a single secure settings value + * as an integer. Note that internally setting values are always + * stored as strings; this function converts the string to an integer + * for you. The default value will be returned if the setting is + * not defined or not an integer. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * @param def Value to return if the setting is not defined. + * + * @return The setting's current value, or 'def' if it is not defined + * or not a valid integer. + */ + public static int getInt(ContentResolver cr, String name, int def) { + return getIntForUser(cr, name, def, cr.getUserId()); + } + + /** @hide */ + public static int getIntForUser(ContentResolver cr, String name, int def, int userHandle) { + if (LOCATION_MODE.equals(name)) { + // Map from to underlying location provider storage API to location mode + return getLocationModeForUser(cr, userHandle); + } + String v = getStringForUser(cr, name, userHandle); + try { + return v != null ? Integer.parseInt(v) : def; + } catch (NumberFormatException e) { + return def; + } + } + + /** + * Convenience function for retrieving a single secure settings value + * as an integer. Note that internally setting values are always + * stored as strings; this function converts the string to an integer + * for you. + *

+ * This version does not take a default value. If the setting has not + * been set, or the string value is not a number, + * it throws {@link SettingNotFoundException}. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * + * @throws SettingNotFoundException Thrown if a setting by the given + * name can't be found or the setting value is not an integer. + * + * @return The setting's current value. + */ + public static int getInt(ContentResolver cr, String name) + throws SettingNotFoundException { + return getIntForUser(cr, name, cr.getUserId()); + } + + /** @hide */ + public static int getIntForUser(ContentResolver cr, String name, int userHandle) + throws SettingNotFoundException { + if (LOCATION_MODE.equals(name)) { + // Map from to underlying location provider storage API to location mode + return getLocationModeForUser(cr, userHandle); + } + String v = getStringForUser(cr, name, userHandle); + try { + return Integer.parseInt(v); + } catch (NumberFormatException e) { + throw new SettingNotFoundException(name); + } + } + + /** + * Convenience function for updating a single settings value as an + * integer. This will either create a new entry in the table if the + * given name does not exist, or modify the value of the existing row + * with that name. Note that internally setting values are always + * stored as strings, so this function converts the given value to a + * string before storing it. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to modify. + * @param value The new value for the setting. + * @return true if the value was set, false on database errors + */ + public static boolean putInt(ContentResolver cr, String name, int value) { + return putIntForUser(cr, name, value, cr.getUserId()); + } + + /** @hide */ + public static boolean putIntForUser(ContentResolver cr, String name, int value, + int userHandle) { + return putStringForUser(cr, name, Integer.toString(value), userHandle); + } + + /** + * Convenience function for retrieving a single secure settings value + * as a {@code long}. Note that internally setting values are always + * stored as strings; this function converts the string to a {@code long} + * for you. The default value will be returned if the setting is + * not defined or not a {@code long}. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * @param def Value to return if the setting is not defined. + * + * @return The setting's current value, or 'def' if it is not defined + * or not a valid {@code long}. + */ + public static long getLong(ContentResolver cr, String name, long def) { + return getLongForUser(cr, name, def, cr.getUserId()); + } + + /** @hide */ + public static long getLongForUser(ContentResolver cr, String name, long def, + int userHandle) { + String valString = getStringForUser(cr, name, userHandle); + long value; + try { + value = valString != null ? Long.parseLong(valString) : def; + } catch (NumberFormatException e) { + value = def; + } + return value; + } + + /** + * Convenience function for retrieving a single secure settings value + * as a {@code long}. Note that internally setting values are always + * stored as strings; this function converts the string to a {@code long} + * for you. + *

+ * This version does not take a default value. If the setting has not + * been set, or the string value is not a number, + * it throws {@link SettingNotFoundException}. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * + * @return The setting's current value. + * @throws SettingNotFoundException Thrown if a setting by the given + * name can't be found or the setting value is not an integer. + */ + public static long getLong(ContentResolver cr, String name) + throws SettingNotFoundException { + return getLongForUser(cr, name, cr.getUserId()); + } + + /** @hide */ + public static long getLongForUser(ContentResolver cr, String name, int userHandle) + throws SettingNotFoundException { + String valString = getStringForUser(cr, name, userHandle); + try { + return Long.parseLong(valString); + } catch (NumberFormatException e) { + throw new SettingNotFoundException(name); + } + } + + /** + * Convenience function for updating a secure settings value as a long + * integer. This will either create a new entry in the table if the + * given name does not exist, or modify the value of the existing row + * with that name. Note that internally setting values are always + * stored as strings, so this function converts the given value to a + * string before storing it. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to modify. + * @param value The new value for the setting. + * @return true if the value was set, false on database errors + */ + public static boolean putLong(ContentResolver cr, String name, long value) { + return putLongForUser(cr, name, value, cr.getUserId()); + } + + /** @hide */ + public static boolean putLongForUser(ContentResolver cr, String name, long value, + int userHandle) { + return putStringForUser(cr, name, Long.toString(value), userHandle); + } + + /** + * Convenience function for retrieving a single secure settings value + * as a floating point number. Note that internally setting values are + * always stored as strings; this function converts the string to an + * float for you. The default value will be returned if the setting + * is not defined or not a valid float. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * @param def Value to return if the setting is not defined. + * + * @return The setting's current value, or 'def' if it is not defined + * or not a valid float. + */ + public static float getFloat(ContentResolver cr, String name, float def) { + return getFloatForUser(cr, name, def, cr.getUserId()); + } + + /** @hide */ + public static float getFloatForUser(ContentResolver cr, String name, float def, + int userHandle) { + String v = getStringForUser(cr, name, userHandle); + try { + return v != null ? Float.parseFloat(v) : def; + } catch (NumberFormatException e) { + return def; + } + } + + /** + * Convenience function for retrieving a single secure settings value + * as a float. Note that internally setting values are always + * stored as strings; this function converts the string to a float + * for you. + *

+ * This version does not take a default value. If the setting has not + * been set, or the string value is not a number, + * it throws {@link SettingNotFoundException}. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * + * @throws SettingNotFoundException Thrown if a setting by the given + * name can't be found or the setting value is not a float. + * + * @return The setting's current value. + */ + public static float getFloat(ContentResolver cr, String name) + throws SettingNotFoundException { + return getFloatForUser(cr, name, cr.getUserId()); + } + + /** @hide */ + public static float getFloatForUser(ContentResolver cr, String name, int userHandle) + throws SettingNotFoundException { + String v = getStringForUser(cr, name, userHandle); + if (v == null) { + throw new SettingNotFoundException(name); + } + try { + return Float.parseFloat(v); + } catch (NumberFormatException e) { + throw new SettingNotFoundException(name); + } + } + + /** + * Convenience function for updating a single settings value as a + * floating point number. This will either create a new entry in the + * table if the given name does not exist, or modify the value of the + * existing row with that name. Note that internally setting values + * are always stored as strings, so this function converts the given + * value to a string before storing it. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to modify. + * @param value The new value for the setting. + * @return true if the value was set, false on database errors + */ + public static boolean putFloat(ContentResolver cr, String name, float value) { + return putFloatForUser(cr, name, value, cr.getUserId()); + } + + /** @hide */ + public static boolean putFloatForUser(ContentResolver cr, String name, float value, + int userHandle) { + return putStringForUser(cr, name, Float.toString(value), userHandle); + } + + /** + * @deprecated Use {@link android.provider.Settings.Global#DEVELOPMENT_SETTINGS_ENABLED} + * instead + */ + @Deprecated + public static final String DEVELOPMENT_SETTINGS_ENABLED = + Global.DEVELOPMENT_SETTINGS_ENABLED; + + /** + * When the user has enable the option to have a "bug report" command + * in the power menu. + * @deprecated Use {@link android.provider.Settings.Global#BUGREPORT_IN_POWER_MENU} instead + * @hide + */ + @Deprecated + public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu"; + + private static final Validator BUGREPORT_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * @deprecated Use {@link android.provider.Settings.Global#ADB_ENABLED} instead + */ + @Deprecated + public static final String ADB_ENABLED = Global.ADB_ENABLED; + + /** + * Setting to allow mock locations and location provider status to be injected into the + * LocationManager service for testing purposes during application development. These + * locations and status values override actual location and status information generated + * by network, gps, or other location providers. + * + * @deprecated This settings is not used anymore. + */ + @Deprecated + public static final String ALLOW_MOCK_LOCATION = "mock_location"; + + private static final Validator ALLOW_MOCK_LOCATION_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * On Android 8.0 (API level 26) and higher versions of the platform, + * a 64-bit number (expressed as a hexadecimal string), unique to + * each combination of app-signing key, user, and device. + * Values of {@code ANDROID_ID} are scoped by signing key and user. + * The value may change if a factory reset is performed on the + * device or if an APK signing key changes. + * + * For more information about how the platform handles {@code ANDROID_ID} + * in Android 8.0 (API level 26) and higher, see + * Android 8.0 Behavior Changes. + * + *

Note: For apps that were installed + * prior to updating the device to a version of Android 8.0 + * (API level 26) or higher, the value of {@code ANDROID_ID} changes + * if the app is uninstalled and then reinstalled after the OTA. + * To preserve values across uninstalls after an OTA to Android 8.0 + * or higher, developers can use + * + * Key/Value Backup.

+ * + *

In versions of the platform lower than Android 8.0 (API level 26), + * a 64-bit number (expressed as a hexadecimal string) that is randomly + * generated when the user first sets up the device and should remain + * constant for the lifetime of the user's device. + * + * On devices that have + * + * multiple users, each user appears as a + * completely separate device, so the {@code ANDROID_ID} value is + * unique to each user.

+ * + *

Note: If the caller is an Instant App the ID is scoped + * to the Instant App, it is generated when the Instant App is first installed and reset if + * the user clears the Instant App. + */ + public static final String ANDROID_ID = "android_id"; + + /** + * @deprecated Use {@link android.provider.Settings.Global#BLUETOOTH_ON} instead + */ + @Deprecated + public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON; + + private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead + */ + @Deprecated + public static final String DATA_ROAMING = Global.DATA_ROAMING; + + /** + * Setting to record the input method used by default, holding the ID + * of the desired method. + */ + public static final String DEFAULT_INPUT_METHOD = "default_input_method"; + + /** + * Setting to record the input method subtype used by default, holding the ID + * of the desired method. + */ + public static final String SELECTED_INPUT_METHOD_SUBTYPE = + "selected_input_method_subtype"; + + /** + * Setting to record the history of input method subtype, holding the pair of ID of IME + * and its last used subtype. + * @hide + */ + public static final String INPUT_METHODS_SUBTYPE_HISTORY = + "input_methods_subtype_history"; + + /** + * Setting to record the visibility of input method selector + */ + public static final String INPUT_METHOD_SELECTOR_VISIBILITY = + "input_method_selector_visibility"; + + /** + * The currently selected voice interaction service flattened ComponentName. + * @hide + */ + @TestApi + public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service"; + + /** + * The currently selected autofill service flattened ComponentName. + * @hide + */ + @TestApi + public static final String AUTOFILL_SERVICE = "autofill_service"; + + private static final Validator AUTOFILL_SERVICE_VALIDATOR = + NULLABLE_COMPONENT_NAME_VALIDATOR; + + /** + * Boolean indicating if Autofill supports field classification. + * + * @see android.service.autofill.AutofillService + * + * @hide + */ + @SystemApi + @TestApi + public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION = + "autofill_field_classification"; + + /** + * Defines value returned by {@link android.service.autofill.UserData#getMaxUserDataSize()}. + * + * @hide + */ + @SystemApi + @TestApi + public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE = + "autofill_user_data_max_user_data_size"; + + /** + * Defines value returned by + * {@link android.service.autofill.UserData#getMaxFieldClassificationIdsSize()}. + * + * @hide + */ + @SystemApi + @TestApi + public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE = + "autofill_user_data_max_field_classification_size"; + + /** + * Defines value returned by + * {@link android.service.autofill.UserData#getMaxCategoryCount()}. + * + * @hide + */ + @SystemApi + @TestApi + public static final String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT = + "autofill_user_data_max_category_count"; + + /** + * Defines value returned by {@link android.service.autofill.UserData#getMaxValueLength()}. + * + * @hide + */ + @SystemApi + @TestApi + public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH = + "autofill_user_data_max_value_length"; + + /** + * Defines value returned by {@link android.service.autofill.UserData#getMinValueLength()}. + * + * @hide + */ + @SystemApi + @TestApi + public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH = + "autofill_user_data_min_value_length"; + + /** + * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead + */ + @Deprecated + public static final String DEVICE_PROVISIONED = Global.DEVICE_PROVISIONED; + + /** + * Whether the current user has been set up via setup wizard (0 = false, 1 = true) + * @hide + */ + @TestApi + public static final String USER_SETUP_COMPLETE = "user_setup_complete"; + + /** + * The current state of device personalization. + * + * @hide + * @see UserSetupPersonalization + */ + public static final String USER_SETUP_PERSONALIZATION_STATE = + "user_setup_personalization_state"; + + /** + * Whether the current user has been set up via setup wizard (0 = false, 1 = true) + * This value differs from USER_SETUP_COMPLETE in that it can be reset back to 0 + * in case SetupWizard has been re-enabled on TV devices. + * + * @hide + */ + public static final String TV_USER_SETUP_COMPLETE = "tv_user_setup_complete"; + + /** + * Prefix for category name that marks whether a suggested action from that category was + * completed. + * @hide + */ + public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category."; + + /** + * List of input methods that are currently enabled. This is a string + * containing the IDs of all enabled input methods, each ID separated + * by ':'. + * + * Format like "ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0" + * where imeId is ComponentName and subtype is int32. + */ + public static final String ENABLED_INPUT_METHODS = "enabled_input_methods"; + + /** + * List of system input methods that are currently disabled. This is a string + * containing the IDs of all disabled input methods, each ID separated + * by ':'. + * @hide + */ + public static final String DISABLED_SYSTEM_INPUT_METHODS = "disabled_system_input_methods"; + + /** + * Whether to show the IME when a hard keyboard is connected. This is a boolean that + * determines if the IME should be shown when a hard keyboard is attached. + * @hide + */ + public static final String SHOW_IME_WITH_HARD_KEYBOARD = "show_ime_with_hard_keyboard"; + + private static final Validator SHOW_IME_WITH_HARD_KEYBOARD_VALIDATOR = BOOLEAN_VALIDATOR; + + /** + * Host name and port for global http proxy. Uses ':' seperator for + * between host and port. + * + * @deprecated Use {@link Global#HTTP_PROXY} + */ + @Deprecated + public static final String HTTP_PROXY = Global.HTTP_PROXY; + + /** + * Package designated as always-on VPN provider. + * + * @hide + */ + public static final String ALWAYS_ON_VPN_APP = "always_on_vpn_app"; + + /** + * Whether to block networking outside of VPN connections while always-on is set. + * @see #ALWAYS_ON_VPN_APP + * + * @hide + */ + public static final String ALWAYS_ON_VPN_LOCKDOWN = "always_on_vpn_lockdown"; + + /** + * Whether applications can be installed for this user via the system's + * {@link Intent#ACTION_INSTALL_PACKAGE} mechanism. * - * @see #resetToDefaults(ContentResolver, String) + *

1 = permit app installation via the system package installer intent + *

0 = do not allow use of the package installer + * @deprecated Starting from {@link android.os.Build.VERSION_CODES#O}, apps should use + * {@link PackageManager#canRequestPackageInstalls()} + * @see PackageManager#canRequestPackageInstalls() + */ + public static final String INSTALL_NON_MARKET_APPS = "install_non_market_apps"; + + /** + * A flag to tell {@link com.android.server.devicepolicy.DevicePolicyManagerService} that + * the default for {@link #INSTALL_NON_MARKET_APPS} is reversed for this user on OTA. So it + * can set the restriction {@link android.os.UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} + * on behalf of the profile owner if needed to make the change transparent for profile + * owners. * * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) - public static boolean putString(@NonNull ContentResolver resolver, - @NonNull String name, @Nullable String value, @Nullable String tag, - boolean makeDefault) { - return putStringForUser(resolver, name, value, tag, makeDefault, - resolver.getUserId()); - } + public static final String UNKNOWN_SOURCES_DEFAULT_REVERSED = + "unknown_sources_default_reversed"; /** - * Reset the settings to their defaults. This would reset only - * settings set by the caller's package. Think of it of a way to undo your own - * changes to the global settings. Passing in the optional tag will reset only - * settings changed by your package and associated with this tag. - * - * @param resolver Handle to the content resolver. - * @param tag Optional tag which should be associated with the settings to reset. + * Comma-separated list of location providers that activities may access. Do not rely on + * this value being present in settings.db or on ContentObserver notifications on the + * corresponding Uri. * - * @see #putString(ContentResolver, String, String, String, boolean) + * @deprecated use {@link #LOCATION_MODE} and + * {@link LocationManager#MODE_CHANGED_ACTION} (or + * {@link LocationManager#PROVIDERS_CHANGED_ACTION}) + */ + @Deprecated + public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed"; + + /** + * The degree of location access enabled by the user. + *

+ * When used with {@link #putInt(ContentResolver, String, int)}, must be one of {@link + * #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, {@link + * #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. When used with {@link + * #getInt(ContentResolver, String)}, the caller must gracefully handle additional location + * modes that might be added in the future. + *

+ * Note: do not rely on this value being present in settings.db or on ContentObserver + * notifications for the corresponding Uri. Use {@link LocationManager#MODE_CHANGED_ACTION} + * to receive changes in this value. * + * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To + * get the status of a location provider, use + * {@link LocationManager#isProviderEnabled(String)}. + */ + @Deprecated + public static final String LOCATION_MODE = "location_mode"; + + /** + * The App or module that changes the location mode. * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) - public static void resetToDefaults(@NonNull ContentResolver resolver, - @Nullable String tag) { - resetToDefaultsAsUser(resolver, tag, RESET_MODE_PACKAGE_DEFAULTS, - resolver.getUserId()); - } + public static final String LOCATION_CHANGER = "location_changer"; + /** + * The location changer is unknown or unable to detect. + * @hide + */ + public static final int LOCATION_CHANGER_UNKNOWN = 0; + /** + * Location settings in system settings. + * @hide + */ + public static final int LOCATION_CHANGER_SYSTEM_SETTINGS = 1; + /** + * The location icon in drop down notification drawer. + * @hide + */ + public static final int LOCATION_CHANGER_QUICK_SETTINGS = 2; /** + * Location access disabled. * - * Reset the settings to their defaults for a given user with a specific mode. The - * optional tag argument is valid only for {@link #RESET_MODE_PACKAGE_DEFAULTS} - * allowing resetting the settings made by a package and associated with the tag. + * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To + * get the status of a location provider, use + * {@link LocationManager#isProviderEnabled(String)}. + */ + @Deprecated + public static final int LOCATION_MODE_OFF = 0; + + /** + * Network Location Provider disabled, but GPS and other sensors enabled. * - * @param resolver Handle to the content resolver. - * @param tag Optional tag which should be associated with the settings to reset. - * @param mode The reset mode. - * @param userHandle The user for which to reset to defaults. + * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To + * get the status of a location provider, use + * {@link LocationManager#isProviderEnabled(String)}. + */ + @Deprecated + public static final int LOCATION_MODE_SENSORS_ONLY = 1; + + /** + * Reduced power usage, such as limiting the number of GPS updates per hour. Requests + * with {@link android.location.Criteria#POWER_HIGH} may be downgraded to + * {@link android.location.Criteria#POWER_MEDIUM}. * - * @see #RESET_MODE_PACKAGE_DEFAULTS - * @see #RESET_MODE_UNTRUSTED_DEFAULTS - * @see #RESET_MODE_UNTRUSTED_CHANGES - * @see #RESET_MODE_TRUSTED_DEFAULTS + * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To + * get the status of a location provider, use + * {@link LocationManager#isProviderEnabled(String)}. + */ + @Deprecated + public static final int LOCATION_MODE_BATTERY_SAVING = 2; + + /** + * Best-effort location computation allowed. * + * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To + * get the status of a location provider, use + * {@link LocationManager#isProviderEnabled(String)}. + */ + @Deprecated + public static final int LOCATION_MODE_HIGH_ACCURACY = 3; + + /** + * A flag containing settings used for biometric weak * @hide */ - public static void resetToDefaultsAsUser(@NonNull ContentResolver resolver, - @Nullable String tag, @ResetMode int mode, @IntRange(from = 0) int userHandle) { - try { - Bundle arg = new Bundle(); - arg.putInt(CALL_METHOD_USER_KEY, userHandle); - if (tag != null) { - arg.putString(CALL_METHOD_TAG_KEY, tag); - } - arg.putInt(CALL_METHOD_RESET_MODE_KEY, mode); - IContentProvider cp = sProviderHolder.getProvider(resolver); - cp.call(resolver.getPackageName(), CALL_METHOD_RESET_SECURE, null, arg); - } catch (RemoteException e) { - Log.w(TAG, "Can't reset do defaults for " + CONTENT_URI, e); - } - } + @Deprecated + public static final String LOCK_BIOMETRIC_WEAK_FLAGS = + "lock_biometric_weak_flags"; /** - * Construct the content URI for a particular name/value pair, - * useful for monitoring changes with a ContentObserver. - * @param name to look up in the table - * @return the corresponding content URI, or null if not present + * Whether lock-to-app will lock the keyguard when exiting. + * @hide */ - public static Uri getUriFor(String name) { - if (MOVED_TO_GLOBAL.contains(name)) { - Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" - + " to android.provider.Settings.Global, returning global URI."); - return Global.getUriFor(Global.CONTENT_URI, name); - } - return getUriFor(CONTENT_URI, name); - } + public static final String LOCK_TO_APP_EXIT_LOCKED = "lock_to_app_exit_locked"; /** - * Convenience function for retrieving a single secure settings value - * as an integer. Note that internally setting values are always - * stored as strings; this function converts the string to an integer - * for you. The default value will be returned if the setting is - * not defined or not an integer. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to retrieve. - * @param def Value to return if the setting is not defined. + * Whether autolock is enabled (0 = false, 1 = true) * - * @return The setting's current value, or 'def' if it is not defined - * or not a valid integer. + * @deprecated Use {@link android.app.KeyguardManager} to determine the state and security + * level of the keyguard. Accessing this setting from an app that is targeting + * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. */ - public static int getInt(ContentResolver cr, String name, int def) { - return getIntForUser(cr, name, def, cr.getUserId()); - } - - /** @hide */ - public static int getIntForUser(ContentResolver cr, String name, int def, int userHandle) { - if (LOCATION_MODE.equals(name)) { - // Map from to underlying location provider storage API to location mode - return getLocationModeForUser(cr, userHandle); - } - String v = getStringForUser(cr, name, userHandle); - try { - return v != null ? Integer.parseInt(v) : def; - } catch (NumberFormatException e) { - return def; - } - } + @Deprecated + public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock"; /** - * Convenience function for retrieving a single secure settings value - * as an integer. Note that internally setting values are always - * stored as strings; this function converts the string to an integer - * for you. - *

- * This version does not take a default value. If the setting has not - * been set, or the string value is not a number, - * it throws {@link SettingNotFoundException}. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to retrieve. - * - * @throws SettingNotFoundException Thrown if a setting by the given - * name can't be found or the setting value is not an integer. + * Whether lock pattern is visible as user enters (0 = false, 1 = true) * - * @return The setting's current value. + * @deprecated Accessing this setting from an app that is targeting + * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. */ - public static int getInt(ContentResolver cr, String name) - throws SettingNotFoundException { - return getIntForUser(cr, name, cr.getUserId()); - } + @Deprecated + public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; - /** @hide */ - public static int getIntForUser(ContentResolver cr, String name, int userHandle) - throws SettingNotFoundException { - if (LOCATION_MODE.equals(name)) { - // Map from to underlying location provider storage API to location mode - return getLocationModeForUser(cr, userHandle); - } - String v = getStringForUser(cr, name, userHandle); - try { - return Integer.parseInt(v); - } catch (NumberFormatException e) { - throw new SettingNotFoundException(name); - } - } + /** + * Whether lock pattern will vibrate as user enters (0 = false, 1 = + * true) + * + * @deprecated Starting in {@link VERSION_CODES#JELLY_BEAN_MR1} the + * lockscreen uses + * {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}. + * Accessing this setting from an app that is targeting + * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. + */ + @Deprecated + public static final String + LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; /** - * Convenience function for updating a single settings value as an - * integer. This will either create a new entry in the table if the - * given name does not exist, or modify the value of the existing row - * with that name. Note that internally setting values are always - * stored as strings, so this function converts the given value to a - * string before storing it. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to modify. - * @param value The new value for the setting. - * @return true if the value was set, false on database errors + * This preference allows the device to be locked given time after screen goes off, + * subject to current DeviceAdmin policy limits. + * @hide */ - public static boolean putInt(ContentResolver cr, String name, int value) { - return putIntForUser(cr, name, value, cr.getUserId()); - } + public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout"; - /** @hide */ - public static boolean putIntForUser(ContentResolver cr, String name, int value, - int userHandle) { - return putStringForUser(cr, name, Integer.toString(value), userHandle); - } /** - * Convenience function for retrieving a single secure settings value - * as a {@code long}. Note that internally setting values are always - * stored as strings; this function converts the string to a {@code long} - * for you. The default value will be returned if the setting is - * not defined or not a {@code long}. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to retrieve. - * @param def Value to return if the setting is not defined. - * - * @return The setting's current value, or 'def' if it is not defined - * or not a valid {@code long}. + * This preference contains the string that shows for owner info on LockScreen. + * @hide + * @deprecated */ - public static long getLong(ContentResolver cr, String name, long def) { - return getLongForUser(cr, name, def, cr.getUserId()); - } + @Deprecated + public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info"; - /** @hide */ - public static long getLongForUser(ContentResolver cr, String name, long def, - int userHandle) { - String valString = getStringForUser(cr, name, userHandle); - long value; - try { - value = valString != null ? Long.parseLong(valString) : def; - } catch (NumberFormatException e) { - value = def; - } - return value; - } + /** + * Ids of the user-selected appwidgets on the lockscreen (comma-delimited). + * @hide + */ + @Deprecated + public static final String LOCK_SCREEN_APPWIDGET_IDS = + "lock_screen_appwidget_ids"; /** - * Convenience function for retrieving a single secure settings value - * as a {@code long}. Note that internally setting values are always - * stored as strings; this function converts the string to a {@code long} - * for you. - *

- * This version does not take a default value. If the setting has not - * been set, or the string value is not a number, - * it throws {@link SettingNotFoundException}. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to retrieve. - * - * @return The setting's current value. - * @throws SettingNotFoundException Thrown if a setting by the given - * name can't be found or the setting value is not an integer. + * Id of the appwidget shown on the lock screen when appwidgets are disabled. + * @hide */ - public static long getLong(ContentResolver cr, String name) - throws SettingNotFoundException { - return getLongForUser(cr, name, cr.getUserId()); - } + @Deprecated + public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID = + "lock_screen_fallback_appwidget_id"; - /** @hide */ - public static long getLongForUser(ContentResolver cr, String name, int userHandle) - throws SettingNotFoundException { - String valString = getStringForUser(cr, name, userHandle); - try { - return Long.parseLong(valString); - } catch (NumberFormatException e) { - throw new SettingNotFoundException(name); - } - } + /** + * Index of the lockscreen appwidget to restore, -1 if none. + * @hide + */ + @Deprecated + public static final String LOCK_SCREEN_STICKY_APPWIDGET = + "lock_screen_sticky_appwidget"; /** - * Convenience function for updating a secure settings value as a long - * integer. This will either create a new entry in the table if the - * given name does not exist, or modify the value of the existing row - * with that name. Note that internally setting values are always - * stored as strings, so this function converts the given value to a - * string before storing it. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to modify. - * @param value The new value for the setting. - * @return true if the value was set, false on database errors + * This preference enables showing the owner info on LockScreen. + * @hide + * @deprecated */ - public static boolean putLong(ContentResolver cr, String name, long value) { - return putLongForUser(cr, name, value, cr.getUserId()); - } + @Deprecated + public static final String LOCK_SCREEN_OWNER_INFO_ENABLED = + "lock_screen_owner_info_enabled"; - /** @hide */ - public static boolean putLongForUser(ContentResolver cr, String name, long value, - int userHandle) { - return putStringForUser(cr, name, Long.toString(value), userHandle); - } + /** + * When set by a user, allows notifications to be shown atop a securely locked screen + * in their full "private" form (same as when the device is unlocked). + * @hide + */ + public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = + "lock_screen_allow_private_notifications"; /** - * Convenience function for retrieving a single secure settings value - * as a floating point number. Note that internally setting values are - * always stored as strings; this function converts the string to an - * float for you. The default value will be returned if the setting - * is not defined or not a valid float. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to retrieve. - * @param def Value to return if the setting is not defined. - * - * @return The setting's current value, or 'def' if it is not defined - * or not a valid float. + * When set by a user, allows notification remote input atop a securely locked screen + * without having to unlock + * @hide */ - public static float getFloat(ContentResolver cr, String name, float def) { - return getFloatForUser(cr, name, def, cr.getUserId()); - } + public static final String LOCK_SCREEN_ALLOW_REMOTE_INPUT = + "lock_screen_allow_remote_input"; - /** @hide */ - public static float getFloatForUser(ContentResolver cr, String name, float def, - int userHandle) { - String v = getStringForUser(cr, name, userHandle); - try { - return v != null ? Float.parseFloat(v) : def; - } catch (NumberFormatException e) { - return def; - } - } + /** + * Set by the system to track if the user needs to see the call to action for + * the lockscreen notification policy. + * @hide + */ + public static final String SHOW_NOTE_ABOUT_NOTIFICATION_HIDING = + "show_note_about_notification_hiding"; /** - * Convenience function for retrieving a single secure settings value - * as a float. Note that internally setting values are always - * stored as strings; this function converts the string to a float - * for you. - *

- * This version does not take a default value. If the setting has not - * been set, or the string value is not a number, - * it throws {@link SettingNotFoundException}. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to retrieve. - * - * @throws SettingNotFoundException Thrown if a setting by the given - * name can't be found or the setting value is not a float. - * - * @return The setting's current value. + * Set to 1 by the system after trust agents have been initialized. + * @hide */ - public static float getFloat(ContentResolver cr, String name) - throws SettingNotFoundException { - return getFloatForUser(cr, name, cr.getUserId()); - } + public static final String TRUST_AGENTS_INITIALIZED = + "trust_agents_initialized"; - /** @hide */ - public static float getFloatForUser(ContentResolver cr, String name, int userHandle) - throws SettingNotFoundException { - String v = getStringForUser(cr, name, userHandle); - if (v == null) { - throw new SettingNotFoundException(name); - } - try { - return Float.parseFloat(v); - } catch (NumberFormatException e) { - throw new SettingNotFoundException(name); - } - } + /** + * The Logging ID (a unique 64-bit value) as a hex string. + * Used as a pseudonymous identifier for logging. + * @deprecated This identifier is poorly initialized and has + * many collisions. It should not be used. + */ + @Deprecated + public static final String LOGGING_ID = "logging_id"; /** - * Convenience function for updating a single settings value as a - * floating point number. This will either create a new entry in the - * table if the given name does not exist, or modify the value of the - * existing row with that name. Note that internally setting values - * are always stored as strings, so this function converts the given - * value to a string before storing it. - * - * @param cr The ContentResolver to access. - * @param name The name of the setting to modify. - * @param value The new value for the setting. - * @return true if the value was set, false on database errors + * @deprecated Use {@link android.provider.Settings.Global#NETWORK_PREFERENCE} instead */ - public static boolean putFloat(ContentResolver cr, String name, float value) { - return putFloatForUser(cr, name, value, cr.getUserId()); - } + @Deprecated + public static final String NETWORK_PREFERENCE = Global.NETWORK_PREFERENCE; - /** @hide */ - public static boolean putFloatForUser(ContentResolver cr, String name, float value, - int userHandle) { - return putStringForUser(cr, name, Float.toString(value), userHandle); - } + /** + * No longer supported. + */ + public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled"; + + /** + * No longer supported. + */ + public static final String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update"; + + /** + * No longer supported. + */ + public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url"; /** - * @deprecated Use {@link android.provider.Settings.Global#DEVELOPMENT_SETTINGS_ENABLED} - * instead + * Settings classname to launch when Settings is clicked from All + * Applications. Needed because of user testing between the old + * and new Settings apps. */ - @Deprecated - public static final String DEVELOPMENT_SETTINGS_ENABLED = - Global.DEVELOPMENT_SETTINGS_ENABLED; + // TODO: 881807 + public static final String SETTINGS_CLASSNAME = "settings_classname"; /** - * When the user has enable the option to have a "bug report" command - * in the power menu. - * @deprecated Use {@link android.provider.Settings.Global#BUGREPORT_IN_POWER_MENU} instead - * @hide + * @deprecated Use {@link android.provider.Settings.Global#USB_MASS_STORAGE_ENABLED} instead */ @Deprecated - public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu"; + public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED; - private static final Validator BUGREPORT_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#ADB_ENABLED} instead + * @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead */ @Deprecated - public static final String ADB_ENABLED = Global.ADB_ENABLED; + public static final String USE_GOOGLE_MAIL = Global.USE_GOOGLE_MAIL; /** - * Setting to allow mock locations and location provider status to be injected into the - * LocationManager service for testing purposes during application development. These - * locations and status values override actual location and status information generated - * by network, gps, or other location providers. - * - * @deprecated This settings is not used anymore. + * If accessibility is enabled. */ - @Deprecated - public static final String ALLOW_MOCK_LOCATION = "mock_location"; + public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled"; - private static final Validator ALLOW_MOCK_LOCATION_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator ACCESSIBILITY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * On Android 8.0 (API level 26) and higher versions of the platform, - * a 64-bit number (expressed as a hexadecimal string), unique to - * each combination of app-signing key, user, and device. - * Values of {@code ANDROID_ID} are scoped by signing key and user. - * The value may change if a factory reset is performed on the - * device or if an APK signing key changes. - * - * For more information about how the platform handles {@code ANDROID_ID} - * in Android 8.0 (API level 26) and higher, see - * Android 8.0 Behavior Changes. - * - *

Note: For apps that were installed - * prior to updating the device to a version of Android 8.0 - * (API level 26) or higher, the value of {@code ANDROID_ID} changes - * if the app is uninstalled and then reinstalled after the OTA. - * To preserve values across uninstalls after an OTA to Android 8.0 - * or higher, developers can use - * - * Key/Value Backup.

- * - *

In versions of the platform lower than Android 8.0 (API level 26), - * a 64-bit number (expressed as a hexadecimal string) that is randomly - * generated when the user first sets up the device and should remain - * constant for the lifetime of the user's device. - * - * On devices that have - * - * multiple users, each user appears as a - * completely separate device, so the {@code ANDROID_ID} value is - * unique to each user.

- * - *

Note: If the caller is an Instant App the ID is scoped - * to the Instant App, it is generated when the Instant App is first installed and reset if - * the user clears the Instant App. + * Setting specifying if the accessibility shortcut is enabled. + * @hide */ - public static final String ANDROID_ID = "android_id"; + public static final String ACCESSIBILITY_SHORTCUT_ENABLED = + "accessibility_shortcut_enabled"; + + private static final Validator ACCESSIBILITY_SHORTCUT_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#BLUETOOTH_ON} instead + * Setting specifying if the accessibility shortcut is enabled. + * @hide */ - @Deprecated - public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON; + public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN = + "accessibility_shortcut_on_lock_screen"; - private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead + * Setting specifying if the accessibility shortcut dialog has been shown to this user. + * @hide */ - @Deprecated - public static final String DATA_ROAMING = Global.DATA_ROAMING; + public static final String ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN = + "accessibility_shortcut_dialog_shown"; + + private static final Validator ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Setting to record the input method used by default, holding the ID - * of the desired method. + * Setting specifying the accessibility service to be toggled via the accessibility + * shortcut. Must be its flattened {@link ComponentName}. + * @hide */ - public static final String DEFAULT_INPUT_METHOD = "default_input_method"; + public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE = + "accessibility_shortcut_target_service"; + + private static final Validator ACCESSIBILITY_SHORTCUT_TARGET_SERVICE_VALIDATOR = + NULLABLE_COMPONENT_NAME_VALIDATOR; /** - * Setting to record the input method subtype used by default, holding the ID - * of the desired method. + * Setting specifying the accessibility service or feature to be toggled via the + * accessibility button in the navigation bar. This is either a flattened + * {@link ComponentName} or the class name of a system class implementing a supported + * accessibility feature. + * @hide */ - public static final String SELECTED_INPUT_METHOD_SUBTYPE = - "selected_input_method_subtype"; + public static final String ACCESSIBILITY_BUTTON_TARGET_COMPONENT = + "accessibility_button_target_component"; + + private static final Validator ACCESSIBILITY_BUTTON_TARGET_COMPONENT_VALIDATOR = + new Validator() { + @Override + public boolean validate(@Nullable String value) { + // technically either ComponentName or class name, but there's proper value + // validation at callsites, so allow any non-null string + return value != null; + } + }; /** - * Setting to record the history of input method subtype, holding the pair of ID of IME - * and its last used subtype. - * @hide + * If touch exploration is enabled. */ - public static final String INPUT_METHODS_SUBTYPE_HISTORY = - "input_methods_subtype_history"; + public static final String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled"; + + private static final Validator TOUCH_EXPLORATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Setting to record the visibility of input method selector + * List of the enabled accessibility providers. */ - public static final String INPUT_METHOD_SELECTOR_VISIBILITY = - "input_method_selector_visibility"; + public static final String ENABLED_ACCESSIBILITY_SERVICES = + "enabled_accessibility_services"; + + private static final Validator ENABLED_ACCESSIBILITY_SERVICES_VALIDATOR = + new SettingsValidators.ComponentNameListValidator(":"); /** - * The currently selected voice interaction service flattened ComponentName. + * List of the accessibility services to which the user has granted + * permission to put the device into touch exploration mode. + * * @hide */ - @TestApi - public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service"; + public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES = + "touch_exploration_granted_accessibility_services"; + + private static final Validator TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES_VALIDATOR = + new SettingsValidators.ComponentNameListValidator(":"); /** - * The currently selected autofill service flattened ComponentName. + * Whether the hush gesture has ever been used // TODO: beverlyt * @hide */ - @TestApi - public static final String AUTOFILL_SERVICE = "autofill_service"; + public static final String HUSH_GESTURE_USED = "hush_gesture_used"; - private static final Validator AUTOFILL_SERVICE_VALIDATOR = - NULLABLE_COMPONENT_NAME_VALIDATOR; + private static final Validator HUSH_GESTURE_USED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Boolean indicating if Autofill supports field classification. - * - * @see android.service.autofill.AutofillService - * + * Number of times the user has manually clicked the ringer toggle * @hide */ - @SystemApi - @TestApi - public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION = - "autofill_field_classification"; + public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count"; + + private static final Validator MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Defines value returned by {@link android.service.autofill.UserData#getMaxUserDataSize()}. + * Uri of the slice that's presented on the keyguard. + * Defaults to a slice with the date and next alarm. * * @hide */ - @SystemApi - @TestApi - public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE = - "autofill_user_data_max_user_data_size"; + public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri"; /** - * Defines value returned by - * {@link android.service.autofill.UserData#getMaxFieldClassificationIdsSize()}. + * Whether to speak passwords while in accessibility mode. * - * @hide + * @deprecated The speaking of passwords is controlled by individual accessibility services. + * Apps should ignore this setting and provide complete information to accessibility + * at all times, which was the behavior when this value was {@code true}. */ - @SystemApi - @TestApi - public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE = - "autofill_user_data_max_field_classification_size"; + @Deprecated + public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password"; + + private static final Validator ACCESSIBILITY_SPEAK_PASSWORD_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Defines value returned by - * {@link android.service.autofill.UserData#getMaxCategoryCount()}. + * Indicates whether a DPC has been downloaded during provisioning. + * + *

Type: int (0 for false, 1 for true) + * + *

If this is true, then any attempts to begin setup again should result in factory reset * * @hide */ - @SystemApi - @TestApi - public static final String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT = - "autofill_user_data_max_category_count"; + public static final String MANAGED_PROVISIONING_DPC_DOWNLOADED = + "managed_provisioning_dpc_downloaded"; /** - * Defines value returned by {@link android.service.autofill.UserData#getMaxValueLength()}. + * Whether to draw text with high contrast while in accessibility mode. * * @hide */ - @SystemApi - @TestApi - public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH = - "autofill_user_data_max_value_length"; + public static final String ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED = + "high_text_contrast_enabled"; + + private static final Validator ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Defines value returned by {@link android.service.autofill.UserData#getMinValueLength()}. + * Setting that specifies whether the display magnification is enabled via a system-wide + * triple tap gesture. Display magnifications allows the user to zoom in the display content + * and is targeted to low vision users. The current magnification scale is controlled by + * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE}. * * @hide */ - @SystemApi @TestApi - public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH = - "autofill_user_data_min_value_length"; + public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED = + "accessibility_display_magnification_enabled"; + + private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead + * Setting that specifies whether the display magnification is enabled via a shortcut + * affordance within the system's navigation area. Display magnifications allows the user to + * zoom in the display content and is targeted to low vision users. The current + * magnification scale is controlled by {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE}. + * + * @hide */ - @Deprecated - public static final String DEVICE_PROVISIONED = Global.DEVICE_PROVISIONED; + public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED = + "accessibility_display_magnification_navbar_enabled"; + + private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED_VALIDATOR + = BOOLEAN_VALIDATOR; /** - * Whether the current user has been set up via setup wizard (0 = false, 1 = true) + * Setting that specifies what the display magnification scale is. + * Display magnifications allows the user to zoom in the display + * content and is targeted to low vision users. Whether a display + * magnification is performed is controlled by + * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED} and + * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED} + * * @hide */ - @TestApi - public static final String USER_SETUP_COMPLETE = "user_setup_complete"; + public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE = + "accessibility_display_magnification_scale"; + + private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE_VALIDATOR = + new SettingsValidators.InclusiveFloatRangeValidator(1.0f, Float.MAX_VALUE); /** - * The current state of device personalization. + * Unused mangnification setting * * @hide - * @see UserSetupPersonalization + * @deprecated */ - public static final String USER_SETUP_PERSONALIZATION_STATE = - "user_setup_personalization_state"; + @Deprecated + public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE = + "accessibility_display_magnification_auto_update"; /** - * Whether the current user has been set up via setup wizard (0 = false, 1 = true) - * This value differs from USER_SETUP_COMPLETE in that it can be reset back to 0 - * in case SetupWizard has been re-enabled on TV devices. + * Setting that specifies what mode the soft keyboard is in (default or hidden). Can be + * modified from an AccessibilityService using the SoftKeyboardController. * * @hide */ - public static final String TV_USER_SETUP_COMPLETE = "tv_user_setup_complete"; + public static final String ACCESSIBILITY_SOFT_KEYBOARD_MODE = + "accessibility_soft_keyboard_mode"; /** - * Prefix for category name that marks whether a suggested action from that category was - * completed. + * Default soft keyboard behavior. + * * @hide */ - public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category."; + public static final int SHOW_MODE_AUTO = 0; /** - * List of input methods that are currently enabled. This is a string - * containing the IDs of all enabled input methods, each ID separated - * by ':'. + * Soft keyboard is never shown. * - * Format like "ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0" - * where imeId is ComponentName and subtype is int32. + * @hide */ - public static final String ENABLED_INPUT_METHODS = "enabled_input_methods"; + public static final int SHOW_MODE_HIDDEN = 1; /** - * List of system input methods that are currently disabled. This is a string - * containing the IDs of all disabled input methods, each ID separated - * by ':'. + * Setting that specifies whether timed text (captions) should be + * displayed in video content. Text display properties are controlled by + * the following settings: + *

    + *
  • {@link #ACCESSIBILITY_CAPTIONING_LOCALE} + *
  • {@link #ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR} + *
  • {@link #ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR} + *
  • {@link #ACCESSIBILITY_CAPTIONING_EDGE_COLOR} + *
  • {@link #ACCESSIBILITY_CAPTIONING_EDGE_TYPE} + *
  • {@link #ACCESSIBILITY_CAPTIONING_TYPEFACE} + *
  • {@link #ACCESSIBILITY_CAPTIONING_FONT_SCALE} + *
+ * * @hide */ - public static final String DISABLED_SYSTEM_INPUT_METHODS = "disabled_system_input_methods"; + public static final String ACCESSIBILITY_CAPTIONING_ENABLED = + "accessibility_captioning_enabled"; + + private static final Validator ACCESSIBILITY_CAPTIONING_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Whether to show the IME when a hard keyboard is connected. This is a boolean that - * determines if the IME should be shown when a hard keyboard is attached. + * Setting that specifies the language for captions as a locale string, + * e.g. en_US. + * + * @see java.util.Locale#toString * @hide */ - public static final String SHOW_IME_WITH_HARD_KEYBOARD = "show_ime_with_hard_keyboard"; + public static final String ACCESSIBILITY_CAPTIONING_LOCALE = + "accessibility_captioning_locale"; - private static final Validator SHOW_IME_WITH_HARD_KEYBOARD_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator ACCESSIBILITY_CAPTIONING_LOCALE_VALIDATOR = LOCALE_VALIDATOR; /** - * Host name and port for global http proxy. Uses ':' seperator for - * between host and port. + * Integer property that specifies the preset style for captions, one + * of: + *
    + *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESET_CUSTOM} + *
  • a valid index of {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESETS} + *
* - * @deprecated Use {@link Global#HTTP_PROXY} + * @see java.util.Locale#toString + * @hide */ - @Deprecated - public static final String HTTP_PROXY = Global.HTTP_PROXY; + public static final String ACCESSIBILITY_CAPTIONING_PRESET = + "accessibility_captioning_preset"; + + private static final Validator ACCESSIBILITY_CAPTIONING_PRESET_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[]{"-1", "0", "1", "2", + "3", "4"}); /** - * Package designated as always-on VPN provider. + * Integer property that specifes the background color for captions as a + * packed 32-bit color. * + * @see android.graphics.Color#argb * @hide */ - public static final String ALWAYS_ON_VPN_APP = "always_on_vpn_app"; + public static final String ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR = + "accessibility_captioning_background_color"; + + private static final Validator ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * Whether to block networking outside of VPN connections while always-on is set. - * @see #ALWAYS_ON_VPN_APP + * Integer property that specifes the foreground color for captions as a + * packed 32-bit color. * + * @see android.graphics.Color#argb * @hide */ - public static final String ALWAYS_ON_VPN_LOCKDOWN = "always_on_vpn_lockdown"; + public static final String ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR = + "accessibility_captioning_foreground_color"; + + private static final Validator ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * Whether applications can be installed for this user via the system's - * {@link Intent#ACTION_INSTALL_PACKAGE} mechanism. + * Integer property that specifes the edge type for captions, one of: + *
    + *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_NONE} + *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_OUTLINE} + *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_DROP_SHADOW} + *
* - *

1 = permit app installation via the system package installer intent - *

0 = do not allow use of the package installer - * @deprecated Starting from {@link android.os.Build.VERSION_CODES#O}, apps should use - * {@link PackageManager#canRequestPackageInstalls()} - * @see PackageManager#canRequestPackageInstalls() + * @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR + * @hide */ - public static final String INSTALL_NON_MARKET_APPS = "install_non_market_apps"; + public static final String ACCESSIBILITY_CAPTIONING_EDGE_TYPE = + "accessibility_captioning_edge_type"; + + private static final Validator ACCESSIBILITY_CAPTIONING_EDGE_TYPE_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[]{"0", "1", "2"}); /** - * A flag to tell {@link com.android.server.devicepolicy.DevicePolicyManagerService} that - * the default for {@link #INSTALL_NON_MARKET_APPS} is reversed for this user on OTA. So it - * can set the restriction {@link android.os.UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} - * on behalf of the profile owner if needed to make the change transparent for profile - * owners. + * Integer property that specifes the edge color for captions as a + * packed 32-bit color. * + * @see #ACCESSIBILITY_CAPTIONING_EDGE_TYPE + * @see android.graphics.Color#argb * @hide */ - public static final String UNKNOWN_SOURCES_DEFAULT_REVERSED = - "unknown_sources_default_reversed"; + public static final String ACCESSIBILITY_CAPTIONING_EDGE_COLOR = + "accessibility_captioning_edge_color"; + + private static final Validator ACCESSIBILITY_CAPTIONING_EDGE_COLOR_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * Comma-separated list of location providers that activities may access. Do not rely on - * this value being present in settings.db or on ContentObserver notifications on the - * corresponding Uri. + * Integer property that specifes the window color for captions as a + * packed 32-bit color. * - * @deprecated use {@link #LOCATION_MODE} and - * {@link LocationManager#MODE_CHANGED_ACTION} (or - * {@link LocationManager#PROVIDERS_CHANGED_ACTION}) + * @see android.graphics.Color#argb + * @hide */ - @Deprecated - public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed"; + public static final String ACCESSIBILITY_CAPTIONING_WINDOW_COLOR = + "accessibility_captioning_window_color"; + + private static final Validator ACCESSIBILITY_CAPTIONING_WINDOW_COLOR_VALIDATOR = + ANY_INTEGER_VALIDATOR; /** - * The degree of location access enabled by the user. - *

- * When used with {@link #putInt(ContentResolver, String, int)}, must be one of {@link - * #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, {@link - * #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. When used with {@link - * #getInt(ContentResolver, String)}, the caller must gracefully handle additional location - * modes that might be added in the future. - *

- * Note: do not rely on this value being present in settings.db or on ContentObserver - * notifications for the corresponding Uri. Use {@link LocationManager#MODE_CHANGED_ACTION} - * to receive changes in this value. + * String property that specifies the typeface for captions, one of: + *

    + *
  • DEFAULT + *
  • MONOSPACE + *
  • SANS_SERIF + *
  • SERIF + *
* - * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To - * get the status of a location provider, use - * {@link LocationManager#isProviderEnabled(String)}. + * @see android.graphics.Typeface + * @hide */ - @Deprecated - public static final String LOCATION_MODE = "location_mode"; + public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE = + "accessibility_captioning_typeface"; + + private static final Validator ACCESSIBILITY_CAPTIONING_TYPEFACE_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[]{"DEFAULT", + "MONOSPACE", "SANS_SERIF", "SERIF"}); /** - * The App or module that changes the location mode. + * Floating point property that specifies font scaling for captions. + * * @hide */ - public static final String LOCATION_CHANGER = "location_changer"; + public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE = + "accessibility_captioning_font_scale"; + + private static final Validator ACCESSIBILITY_CAPTIONING_FONT_SCALE_VALIDATOR = + new SettingsValidators.InclusiveFloatRangeValidator(0.5f, 2.0f); + /** - * The location changer is unknown or unable to detect. - * @hide + * Setting that specifies whether display color inversion is enabled. */ - public static final int LOCATION_CHANGER_UNKNOWN = 0; + public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = + "accessibility_display_inversion_enabled"; + + private static final Validator ACCESSIBILITY_DISPLAY_INVERSION_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + /** - * Location settings in system settings. + * Setting that specifies whether display color space adjustment is + * enabled. + * * @hide */ - public static final int LOCATION_CHANGER_SYSTEM_SETTINGS = 1; + public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED = + "accessibility_display_daltonizer_enabled"; + + private static final Validator ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + /** - * The location icon in drop down notification drawer. + * Integer property that specifies the type of color space adjustment to + * perform. Valid values are defined in AccessibilityManager and Settings arrays.xml: + * - AccessibilityManager.DALTONIZER_DISABLED = -1 + * - AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY = 0 + * - @string/daltonizer_mode_protanomaly = 11 + * - AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY and + * @string/daltonizer_mode_deuteranomaly = 12 + * - @string/daltonizer_mode_tritanomaly = 13 + * * @hide */ - public static final int LOCATION_CHANGER_QUICK_SETTINGS = 2; + public static final String ACCESSIBILITY_DISPLAY_DALTONIZER = + "accessibility_display_daltonizer"; + + private static final Validator ACCESSIBILITY_DISPLAY_DALTONIZER_VALIDATOR = + new SettingsValidators.DiscreteValueValidator( + new String[] {"-1", "0", "11", "12", "13"}); /** - * Location access disabled. + * Setting that specifies whether automatic click when the mouse pointer stops moving is + * enabled. * - * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To - * get the status of a location provider, use - * {@link LocationManager#isProviderEnabled(String)}. + * @hide */ - @Deprecated - public static final int LOCATION_MODE_OFF = 0; + public static final String ACCESSIBILITY_AUTOCLICK_ENABLED = + "accessibility_autoclick_enabled"; + + private static final Validator ACCESSIBILITY_AUTOCLICK_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Network Location Provider disabled, but GPS and other sensors enabled. + * Integer setting specifying amount of time in ms the mouse pointer has to stay still + * before performing click when {@link #ACCESSIBILITY_AUTOCLICK_ENABLED} is set. * - * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To - * get the status of a location provider, use - * {@link LocationManager#isProviderEnabled(String)}. + * @see #ACCESSIBILITY_AUTOCLICK_ENABLED + * @hide */ - @Deprecated - public static final int LOCATION_MODE_SENSORS_ONLY = 1; + public static final String ACCESSIBILITY_AUTOCLICK_DELAY = + "accessibility_autoclick_delay"; + + private static final Validator ACCESSIBILITY_AUTOCLICK_DELAY_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Reduced power usage, such as limiting the number of GPS updates per hour. Requests - * with {@link android.location.Criteria#POWER_HIGH} may be downgraded to - * {@link android.location.Criteria#POWER_MEDIUM}. - * - * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To - * get the status of a location provider, use - * {@link LocationManager#isProviderEnabled(String)}. + * Whether or not larger size icons are used for the pointer of mouse/trackpad for + * accessibility. + * (0 = false, 1 = true) + * @hide */ - @Deprecated - public static final int LOCATION_MODE_BATTERY_SAVING = 2; + public static final String ACCESSIBILITY_LARGE_POINTER_ICON = + "accessibility_large_pointer_icon"; + + private static final Validator ACCESSIBILITY_LARGE_POINTER_ICON_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Best-effort location computation allowed. - * - * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To - * get the status of a location provider, use - * {@link LocationManager#isProviderEnabled(String)}. + * The timeout for considering a press to be a long press in milliseconds. + * @hide */ - @Deprecated - public static final int LOCATION_MODE_HIGH_ACCURACY = 3; + public static final String LONG_PRESS_TIMEOUT = "long_press_timeout"; + + private static final Validator LONG_PRESS_TIMEOUT_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * A flag containing settings used for biometric weak + * The duration in milliseconds between the first tap's up event and the second tap's + * down event for an interaction to be considered part of the same multi-press. * @hide */ - @Deprecated - public static final String LOCK_BIOMETRIC_WEAK_FLAGS = - "lock_biometric_weak_flags"; + public static final String MULTI_PRESS_TIMEOUT = "multi_press_timeout"; /** - * Whether lock-to-app will lock the keyguard when exiting. + * List of the enabled print services. + * + * N and beyond uses {@link #DISABLED_PRINT_SERVICES}. But this might be used in an upgrade + * from pre-N. + * * @hide */ - public static final String LOCK_TO_APP_EXIT_LOCKED = "lock_to_app_exit_locked"; + public static final String ENABLED_PRINT_SERVICES = + "enabled_print_services"; /** - * Whether autolock is enabled (0 = false, 1 = true) + * List of the disabled print services. * - * @deprecated Use {@link android.app.KeyguardManager} to determine the state and security - * level of the keyguard. Accessing this setting from an app that is targeting - * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. + * @hide */ - @Deprecated - public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock"; + @TestApi + public static final String DISABLED_PRINT_SERVICES = + "disabled_print_services"; /** - * Whether lock pattern is visible as user enters (0 = false, 1 = true) + * The saved value for WindowManagerService.setForcedDisplayDensity() + * formatted as a single integer representing DPI. If unset, then use + * the real display density. * - * @deprecated Accessing this setting from an app that is targeting - * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. + * @hide */ - @Deprecated - public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; + public static final String DISPLAY_DENSITY_FORCED = "display_density_forced"; /** - * Whether lock pattern will vibrate as user enters (0 = false, 1 = - * true) + * Setting to always use the default text-to-speech settings regardless + * of the application settings. + * 1 = override application settings, + * 0 = use application settings (if specified). * - * @deprecated Starting in {@link VERSION_CODES#JELLY_BEAN_MR1} the - * lockscreen uses - * {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}. - * Accessing this setting from an app that is targeting - * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. + * @deprecated The value of this setting is no longer respected by + * the framework text to speech APIs as of the Ice Cream Sandwich release. */ @Deprecated - public static final String - LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; + public static final String TTS_USE_DEFAULTS = "tts_use_defaults"; /** - * This preference allows the device to be locked given time after screen goes off, - * subject to current DeviceAdmin policy limits. - * @hide + * Default text-to-speech engine speech rate. 100 = 1x */ - public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout"; + public static final String TTS_DEFAULT_RATE = "tts_default_rate"; + private static final Validator TTS_DEFAULT_RATE_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR; /** - * This preference contains the string that shows for owner info on LockScreen. - * @hide - * @deprecated + * Default text-to-speech engine pitch. 100 = 1x */ - @Deprecated - public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info"; + public static final String TTS_DEFAULT_PITCH = "tts_default_pitch"; + + private static final Validator TTS_DEFAULT_PITCH_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Ids of the user-selected appwidgets on the lockscreen (comma-delimited). - * @hide + * Default text-to-speech engine. */ - @Deprecated - public static final String LOCK_SCREEN_APPWIDGET_IDS = - "lock_screen_appwidget_ids"; + public static final String TTS_DEFAULT_SYNTH = "tts_default_synth"; + + private static final Validator TTS_DEFAULT_SYNTH_VALIDATOR = PACKAGE_NAME_VALIDATOR; /** - * Id of the appwidget shown on the lock screen when appwidgets are disabled. - * @hide + * Default text-to-speech language. + * + * @deprecated this setting is no longer in use, as of the Ice Cream + * Sandwich release. Apps should never need to read this setting directly, + * instead can query the TextToSpeech framework classes for the default + * locale. {@link TextToSpeech#getLanguage()}. */ @Deprecated - public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID = - "lock_screen_fallback_appwidget_id"; + public static final String TTS_DEFAULT_LANG = "tts_default_lang"; /** - * Index of the lockscreen appwidget to restore, -1 if none. - * @hide + * Default text-to-speech country. + * + * @deprecated this setting is no longer in use, as of the Ice Cream + * Sandwich release. Apps should never need to read this setting directly, + * instead can query the TextToSpeech framework classes for the default + * locale. {@link TextToSpeech#getLanguage()}. */ @Deprecated - public static final String LOCK_SCREEN_STICKY_APPWIDGET = - "lock_screen_sticky_appwidget"; + public static final String TTS_DEFAULT_COUNTRY = "tts_default_country"; /** - * This preference enables showing the owner info on LockScreen. - * @hide - * @deprecated + * Default text-to-speech locale variant. + * + * @deprecated this setting is no longer in use, as of the Ice Cream + * Sandwich release. Apps should never need to read this setting directly, + * instead can query the TextToSpeech framework classes for the + * locale that is in use {@link TextToSpeech#getLanguage()}. */ @Deprecated - public static final String LOCK_SCREEN_OWNER_INFO_ENABLED = - "lock_screen_owner_info_enabled"; + public static final String TTS_DEFAULT_VARIANT = "tts_default_variant"; /** - * When set by a user, allows notifications to be shown atop a securely locked screen - * in their full "private" form (same as when the device is unlocked). + * Stores the default tts locales on a per engine basis. Stored as + * a comma seperated list of values, each value being of the form + * {@code engine_name:locale} for example, + * {@code com.foo.ttsengine:eng-USA,com.bar.ttsengine:esp-ESP}. This + * supersedes {@link #TTS_DEFAULT_LANG}, {@link #TTS_DEFAULT_COUNTRY} and + * {@link #TTS_DEFAULT_VARIANT}. Apps should never need to read this + * setting directly, and can query the TextToSpeech framework classes + * for the locale that is in use. + * * @hide */ - public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = - "lock_screen_allow_private_notifications"; + public static final String TTS_DEFAULT_LOCALE = "tts_default_locale"; + + private static final Validator TTS_DEFAULT_LOCALE_VALIDATOR = new Validator() { + @Override + public boolean validate(@Nullable String value) { + if (value == null || value.length() == 0) { + return false; + } + String[] ttsLocales = value.split(","); + boolean valid = true; + for (String ttsLocale : ttsLocales) { + String[] parts = ttsLocale.split(":"); + valid |= ((parts.length == 2) + && (parts[0].length() > 0) + && ANY_STRING_VALIDATOR.validate(parts[0]) + && LOCALE_VALIDATOR.validate(parts[1])); + } + return valid; + } + }; /** - * When set by a user, allows notification remote input atop a securely locked screen - * without having to unlock - * @hide + * Space delimited list of plugin packages that are enabled. */ - public static final String LOCK_SCREEN_ALLOW_REMOTE_INPUT = - "lock_screen_allow_remote_input"; + public static final String TTS_ENABLED_PLUGINS = "tts_enabled_plugins"; + + private static final Validator TTS_ENABLED_PLUGINS_VALIDATOR = + new SettingsValidators.PackageNameListValidator(" "); /** - * Set by the system to track if the user needs to see the call to action for - * the lockscreen notification policy. - * @hide + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON} + * instead. */ - public static final String SHOW_NOTE_ABOUT_NOTIFICATION_HIDING = - "show_note_about_notification_hiding"; + @Deprecated + public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = + Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; + + private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Set to 1 by the system after trust agents have been initialized. - * @hide + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} + * instead. */ - public static final String TRUST_AGENTS_INITIALIZED = - "trust_agents_initialized"; + @Deprecated + public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = + Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY; + + private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * The Logging ID (a unique 64-bit value) as a hex string. - * Used as a pseudonymous identifier for logging. - * @deprecated This identifier is poorly initialized and has - * many collisions. It should not be used. + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT} + * instead. */ @Deprecated - public static final String LOGGING_ID = "logging_id"; + public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = + Global.WIFI_NUM_OPEN_NETWORKS_KEPT; + + private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#NETWORK_PREFERENCE} instead + * @deprecated Use {@link android.provider.Settings.Global#WIFI_ON} + * instead. */ @Deprecated - public static final String NETWORK_PREFERENCE = Global.NETWORK_PREFERENCE; + public static final String WIFI_ON = Global.WIFI_ON; /** - * No longer supported. + * The acceptable packet loss percentage (range 0 - 100) before trying + * another AP on the same network. + * @deprecated This setting is not used. */ - public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled"; + @Deprecated + public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = + "wifi_watchdog_acceptable_packet_loss_percentage"; /** - * No longer supported. + * The number of access points required for a network in order for the + * watchdog to monitor it. + * @deprecated This setting is not used. */ - public static final String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update"; + @Deprecated + public static final String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count"; /** - * No longer supported. + * The delay between background checks. + * @deprecated This setting is not used. */ - public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url"; + @Deprecated + public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = + "wifi_watchdog_background_check_delay_ms"; /** - * Settings classname to launch when Settings is clicked from All - * Applications. Needed because of user testing between the old - * and new Settings apps. + * Whether the Wi-Fi watchdog is enabled for background checking even + * after it thinks the user has connected to a good access point. + * @deprecated This setting is not used. */ - // TODO: 881807 - public static final String SETTINGS_CLASSNAME = "settings_classname"; + @Deprecated + public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = + "wifi_watchdog_background_check_enabled"; /** - * @deprecated Use {@link android.provider.Settings.Global#USB_MASS_STORAGE_ENABLED} instead + * The timeout for a background ping + * @deprecated This setting is not used. */ @Deprecated - public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED; - - private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = + "wifi_watchdog_background_check_timeout_ms"; /** - * @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead + * The number of initial pings to perform that *may* be ignored if they + * fail. Again, if these fail, they will *not* be used in packet loss + * calculation. For example, one network always seemed to time out for + * the first couple pings, so this is set to 3 by default. + * @deprecated This setting is not used. */ @Deprecated - public static final String USE_GOOGLE_MAIL = Global.USE_GOOGLE_MAIL; + public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = + "wifi_watchdog_initial_ignored_ping_count"; /** - * If accessibility is enabled. + * The maximum number of access points (per network) to attempt to test. + * If this number is reached, the watchdog will no longer monitor the + * initial connection state for the network. This is a safeguard for + * networks containing multiple APs whose DNS does not respond to pings. + * @deprecated This setting is not used. */ - public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled"; - - private static final Validator ACCESSIBILITY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + @Deprecated + public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks"; /** - * Setting specifying if the accessibility shortcut is enabled. - * @hide + * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead */ - public static final String ACCESSIBILITY_SHORTCUT_ENABLED = - "accessibility_shortcut_enabled"; - - private static final Validator ACCESSIBILITY_SHORTCUT_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + @Deprecated + public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on"; /** - * Setting specifying if the accessibility shortcut is enabled. - * @hide + * A comma-separated list of SSIDs for which the Wi-Fi watchdog should be enabled. + * @deprecated This setting is not used. */ - public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN = - "accessibility_shortcut_on_lock_screen"; - - private static final Validator ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN_VALIDATOR = - BOOLEAN_VALIDATOR; + @Deprecated + public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list"; /** - * Setting specifying if the accessibility shortcut dialog has been shown to this user. - * @hide + * The number of pings to test if an access point is a good connection. + * @deprecated This setting is not used. */ - public static final String ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN = - "accessibility_shortcut_dialog_shown"; - - private static final Validator ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN_VALIDATOR = - BOOLEAN_VALIDATOR; + @Deprecated + public static final String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count"; /** - * Setting specifying the accessibility service to be toggled via the accessibility - * shortcut. Must be its flattened {@link ComponentName}. - * @hide + * The delay between pings. + * @deprecated This setting is not used. */ - public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE = - "accessibility_shortcut_target_service"; - - private static final Validator ACCESSIBILITY_SHORTCUT_TARGET_SERVICE_VALIDATOR = - NULLABLE_COMPONENT_NAME_VALIDATOR; + @Deprecated + public static final String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms"; /** - * Setting specifying the accessibility service or feature to be toggled via the - * accessibility button in the navigation bar. This is either a flattened - * {@link ComponentName} or the class name of a system class implementing a supported - * accessibility feature. - * @hide + * The timeout per ping. + * @deprecated This setting is not used. */ - public static final String ACCESSIBILITY_BUTTON_TARGET_COMPONENT = - "accessibility_button_target_component"; - - private static final Validator ACCESSIBILITY_BUTTON_TARGET_COMPONENT_VALIDATOR = - new Validator() { - @Override - public boolean validate(@Nullable String value) { - // technically either ComponentName or class name, but there's proper value - // validation at callsites, so allow any non-null string - return value != null; - } - }; + @Deprecated + public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms"; /** - * If touch exploration is enabled. + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_MAX_DHCP_RETRY_COUNT} instead */ - public static final String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled"; - - private static final Validator TOUCH_EXPLORATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + @Deprecated + public static final String WIFI_MAX_DHCP_RETRY_COUNT = Global.WIFI_MAX_DHCP_RETRY_COUNT; /** - * List of the enabled accessibility providers. + * @deprecated Use + * {@link android.provider.Settings.Global#WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS} instead */ - public static final String ENABLED_ACCESSIBILITY_SERVICES = - "enabled_accessibility_services"; - - private static final Validator ENABLED_ACCESSIBILITY_SERVICES_VALIDATOR = - new SettingsValidators.ComponentNameListValidator(":"); + @Deprecated + public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = + Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS; /** - * List of the accessibility services to which the user has granted - * permission to put the device into touch exploration mode. + * The number of milliseconds to hold on to a PendingIntent based request. This delay gives + * the receivers of the PendingIntent an opportunity to make a new network request before + * the Network satisfying the request is potentially removed. * * @hide */ - public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES = - "touch_exploration_granted_accessibility_services"; - - private static final Validator TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES_VALIDATOR = - new SettingsValidators.ComponentNameListValidator(":"); + public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS = + "connectivity_release_pending_intent_delay_ms"; /** - * Whether the hush gesture has ever been used // TODO: beverlyt - * @hide + * Whether background data usage is allowed. + * + * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, + * availability of background data depends on several + * combined factors. When background data is unavailable, + * {@link ConnectivityManager#getActiveNetworkInfo()} will + * now appear disconnected. */ - public static final String HUSH_GESTURE_USED = "hush_gesture_used"; - - private static final Validator HUSH_GESTURE_USED_VALIDATOR = BOOLEAN_VALIDATOR; + @Deprecated + public static final String BACKGROUND_DATA = "background_data"; /** - * Number of times the user has manually clicked the ringer toggle - * @hide + * Origins for which browsers should allow geolocation by default. + * The value is a space-separated list of origins. */ - public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count"; - - private static final Validator MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + public static final String ALLOWED_GEOLOCATION_ORIGINS + = "allowed_geolocation_origins"; /** - * Uri of the slice that's presented on the keyguard. - * Defaults to a slice with the date and next alarm. - * + * The preferred TTY mode 0 = TTy Off, CDMA default + * 1 = TTY Full + * 2 = TTY HCO + * 3 = TTY VCO * @hide */ - public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri"; - - /** - * Whether to speak passwords while in accessibility mode. - * - * @deprecated The speaking of passwords is controlled by individual accessibility services. - * Apps should ignore this setting and provide complete information to accessibility - * at all times, which was the behavior when this value was {@code true}. - */ - @Deprecated - public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password"; + public static final String PREFERRED_TTY_MODE = + "preferred_tty_mode"; - private static final Validator ACCESSIBILITY_SPEAK_PASSWORD_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator PREFERRED_TTY_MODE_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[]{"0", "1", "2", "3"}); /** - * Whether to draw text with high contrast while in accessibility mode. - * + * Whether the enhanced voice privacy mode is enabled. + * 0 = normal voice privacy + * 1 = enhanced voice privacy * @hide */ - public static final String ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED = - "high_text_contrast_enabled"; + public static final String ENHANCED_VOICE_PRIVACY_ENABLED = "enhanced_voice_privacy_enabled"; - private static final Validator ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + private static final Validator ENHANCED_VOICE_PRIVACY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Setting that specifies whether the display magnification is enabled via a system-wide - * triple tap gesture. Display magnifications allows the user to zoom in the display content - * and is targeted to low vision users. The current magnification scale is controlled by - * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE}. - * + * Whether the TTY mode mode is enabled. + * 0 = disabled + * 1 = enabled * @hide */ - @TestApi - public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED = - "accessibility_display_magnification_enabled"; + public static final String TTY_MODE_ENABLED = "tty_mode_enabled"; - private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + private static final Validator TTY_MODE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Setting that specifies whether the display magnification is enabled via a shortcut - * affordance within the system's navigation area. Display magnifications allows the user to - * zoom in the display content and is targeted to low vision users. The current - * magnification scale is controlled by {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE}. - * - * @hide + * User-selected RTT mode. When on, outgoing and incoming calls will be answered as RTT + * calls when supported by the device and carrier. Boolean value. + * 0 = OFF + * 1 = ON */ - public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED = - "accessibility_display_magnification_navbar_enabled"; + public static final String RTT_CALLING_MODE = "rtt_calling_mode"; - private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED_VALIDATOR - = BOOLEAN_VALIDATOR; + private static final Validator RTT_CALLING_MODE_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Setting that specifies what the display magnification scale is. - * Display magnifications allows the user to zoom in the display - * content and is targeted to low vision users. Whether a display - * magnification is performed is controlled by - * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED} and - * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED} - * + /** + * Controls whether settings backup is enabled. + * Type: int ( 0 = disabled, 1 = enabled ) * @hide */ - public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE = - "accessibility_display_magnification_scale"; - - private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE_VALIDATOR = - new SettingsValidators.InclusiveFloatRangeValidator(1.0f, Float.MAX_VALUE); + public static final String BACKUP_ENABLED = "backup_enabled"; /** - * Unused mangnification setting - * + * Controls whether application data is automatically restored from backup + * at install time. + * Type: int ( 0 = disabled, 1 = enabled ) * @hide - * @deprecated */ - @Deprecated - public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE = - "accessibility_display_magnification_auto_update"; + public static final String BACKUP_AUTO_RESTORE = "backup_auto_restore"; /** - * Setting that specifies what mode the soft keyboard is in (default or hidden). Can be - * modified from an AccessibilityService using the SoftKeyboardController. - * + * Indicates whether settings backup has been fully provisioned. + * Type: int ( 0 = unprovisioned, 1 = fully provisioned ) * @hide */ - public static final String ACCESSIBILITY_SOFT_KEYBOARD_MODE = - "accessibility_soft_keyboard_mode"; + public static final String BACKUP_PROVISIONED = "backup_provisioned"; /** - * Default soft keyboard behavior. - * + * Component of the transport to use for backup/restore. * @hide */ - public static final int SHOW_MODE_AUTO = 0; + public static final String BACKUP_TRANSPORT = "backup_transport"; /** - * Soft keyboard is never shown. - * + * Version for which the setup wizard was last shown. Bumped for + * each release when there is new setup information to show. * @hide */ - public static final int SHOW_MODE_HIDDEN = 1; + public static final String LAST_SETUP_SHOWN = "last_setup_shown"; /** - * Setting that specifies whether timed text (captions) should be - * displayed in video content. Text display properties are controlled by - * the following settings: - *
    - *
  • {@link #ACCESSIBILITY_CAPTIONING_LOCALE} - *
  • {@link #ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR} - *
  • {@link #ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR} - *
  • {@link #ACCESSIBILITY_CAPTIONING_EDGE_COLOR} - *
  • {@link #ACCESSIBILITY_CAPTIONING_EDGE_TYPE} - *
  • {@link #ACCESSIBILITY_CAPTIONING_TYPEFACE} - *
  • {@link #ACCESSIBILITY_CAPTIONING_FONT_SCALE} - *
- * + * The interval in milliseconds after which Wi-Fi is considered idle. + * When idle, it is possible for the device to be switched from Wi-Fi to + * the mobile data network. * @hide + * @deprecated Use {@link android.provider.Settings.Global#WIFI_IDLE_MS} + * instead. */ - public static final String ACCESSIBILITY_CAPTIONING_ENABLED = - "accessibility_captioning_enabled"; - - private static final Validator ACCESSIBILITY_CAPTIONING_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + @Deprecated + public static final String WIFI_IDLE_MS = Global.WIFI_IDLE_MS; /** - * Setting that specifies the language for captions as a locale string, - * e.g. en_US. + * The global search provider chosen by the user (if multiple global + * search providers are installed). This will be the provider returned + * by {@link SearchManager#getGlobalSearchActivity()} if it's still + * installed. This setting is stored as a flattened component name as + * per {@link ComponentName#flattenToString()}. * - * @see java.util.Locale#toString * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_LOCALE = - "accessibility_captioning_locale"; - - private static final Validator ACCESSIBILITY_CAPTIONING_LOCALE_VALIDATOR = LOCALE_VALIDATOR; + public static final String SEARCH_GLOBAL_SEARCH_ACTIVITY = + "search_global_search_activity"; /** - * Integer property that specifies the preset style for captions, one - * of: - *
    - *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESET_CUSTOM} - *
  • a valid index of {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESETS} - *
- * - * @see java.util.Locale#toString + * The number of promoted sources in GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_PRESET = - "accessibility_captioning_preset"; - - private static final Validator ACCESSIBILITY_CAPTIONING_PRESET_VALIDATOR = - new SettingsValidators.DiscreteValueValidator(new String[]{"-1", "0", "1", "2", - "3", "4"}); - + public static final String SEARCH_NUM_PROMOTED_SOURCES = "search_num_promoted_sources"; /** - * Integer property that specifes the background color for captions as a - * packed 32-bit color. - * - * @see android.graphics.Color#argb + * The maximum number of suggestions returned by GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR = - "accessibility_captioning_background_color"; - - private static final Validator ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR_VALIDATOR = - ANY_INTEGER_VALIDATOR; - + public static final String SEARCH_MAX_RESULTS_TO_DISPLAY = "search_max_results_to_display"; /** - * Integer property that specifes the foreground color for captions as a - * packed 32-bit color. - * - * @see android.graphics.Color#argb + * The number of suggestions GlobalSearch will ask each non-web search source for. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR = - "accessibility_captioning_foreground_color"; - - private static final Validator ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR_VALIDATOR = - ANY_INTEGER_VALIDATOR; - + public static final String SEARCH_MAX_RESULTS_PER_SOURCE = "search_max_results_per_source"; /** - * Integer property that specifes the edge type for captions, one of: - *
    - *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_NONE} - *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_OUTLINE} - *
  • {@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_DROP_SHADOW} - *
- * - * @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR + * The number of suggestions the GlobalSearch will ask the web search source for. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_EDGE_TYPE = - "accessibility_captioning_edge_type"; - - private static final Validator ACCESSIBILITY_CAPTIONING_EDGE_TYPE_VALIDATOR = - new SettingsValidators.DiscreteValueValidator(new String[]{"0", "1", "2"}); - + public static final String SEARCH_WEB_RESULTS_OVERRIDE_LIMIT = + "search_web_results_override_limit"; /** - * Integer property that specifes the edge color for captions as a - * packed 32-bit color. - * - * @see #ACCESSIBILITY_CAPTIONING_EDGE_TYPE - * @see android.graphics.Color#argb + * The number of milliseconds that GlobalSearch will wait for suggestions from + * promoted sources before continuing with all other sources. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_EDGE_COLOR = - "accessibility_captioning_edge_color"; - - private static final Validator ACCESSIBILITY_CAPTIONING_EDGE_COLOR_VALIDATOR = - ANY_INTEGER_VALIDATOR; - + public static final String SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS = + "search_promoted_source_deadline_millis"; /** - * Integer property that specifes the window color for captions as a - * packed 32-bit color. - * - * @see android.graphics.Color#argb + * The number of milliseconds before GlobalSearch aborts search suggesiton queries. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_WINDOW_COLOR = - "accessibility_captioning_window_color"; - - private static final Validator ACCESSIBILITY_CAPTIONING_WINDOW_COLOR_VALIDATOR = - ANY_INTEGER_VALIDATOR; - + public static final String SEARCH_SOURCE_TIMEOUT_MILLIS = "search_source_timeout_millis"; /** - * String property that specifies the typeface for captions, one of: - *
    - *
  • DEFAULT - *
  • MONOSPACE - *
  • SANS_SERIF - *
  • SERIF - *
- * - * @see android.graphics.Typeface + * The maximum number of milliseconds that GlobalSearch shows the previous results + * after receiving a new query. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE = - "accessibility_captioning_typeface"; - - private static final Validator ACCESSIBILITY_CAPTIONING_TYPEFACE_VALIDATOR = - new SettingsValidators.DiscreteValueValidator(new String[]{"DEFAULT", - "MONOSPACE", "SANS_SERIF", "SERIF"}); - + public static final String SEARCH_PREFILL_MILLIS = "search_prefill_millis"; /** - * Floating point property that specifies font scaling for captions. - * + * The maximum age of log data used for shortcuts in GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE = - "accessibility_captioning_font_scale"; - - private static final Validator ACCESSIBILITY_CAPTIONING_FONT_SCALE_VALIDATOR = - new SettingsValidators.InclusiveFloatRangeValidator(0.5f, 2.0f); - + public static final String SEARCH_MAX_STAT_AGE_MILLIS = "search_max_stat_age_millis"; /** - * Setting that specifies whether display color inversion is enabled. + * The maximum age of log data used for source ranking in GlobalSearch. + * @hide */ - public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = - "accessibility_display_inversion_enabled"; - - private static final Validator ACCESSIBILITY_DISPLAY_INVERSION_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; - + public static final String SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS = + "search_max_source_event_age_millis"; /** - * Setting that specifies whether display color space adjustment is - * enabled. - * + * The minimum number of impressions needed to rank a source in GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED = - "accessibility_display_daltonizer_enabled"; - - private static final Validator ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; - + public static final String SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING = + "search_min_impressions_for_source_ranking"; /** - * Integer property that specifies the type of color space adjustment to - * perform. Valid values are defined in AccessibilityManager and Settings arrays.xml: - * - AccessibilityManager.DALTONIZER_DISABLED = -1 - * - AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY = 0 - * - @string/daltonizer_mode_protanomaly = 11 - * - AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY and - * @string/daltonizer_mode_deuteranomaly = 12 - * - @string/daltonizer_mode_tritanomaly = 13 - * + * The minimum number of clicks needed to rank a source in GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_DISPLAY_DALTONIZER = - "accessibility_display_daltonizer"; - - private static final Validator ACCESSIBILITY_DISPLAY_DALTONIZER_VALIDATOR = - new SettingsValidators.DiscreteValueValidator( - new String[] {"-1", "0", "11", "12", "13"}); - + public static final String SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING = + "search_min_clicks_for_source_ranking"; /** - * Setting that specifies whether automatic click when the mouse pointer stops moving is - * enabled. - * + * The maximum number of shortcuts shown by GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_AUTOCLICK_ENABLED = - "accessibility_autoclick_enabled"; - - private static final Validator ACCESSIBILITY_AUTOCLICK_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; - + public static final String SEARCH_MAX_SHORTCUTS_RETURNED = "search_max_shortcuts_returned"; /** - * Integer setting specifying amount of time in ms the mouse pointer has to stay still - * before performing click when {@link #ACCESSIBILITY_AUTOCLICK_ENABLED} is set. - * - * @see #ACCESSIBILITY_AUTOCLICK_ENABLED + * The size of the core thread pool for suggestion queries in GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_AUTOCLICK_DELAY = - "accessibility_autoclick_delay"; - - private static final Validator ACCESSIBILITY_AUTOCLICK_DELAY_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; - + public static final String SEARCH_QUERY_THREAD_CORE_POOL_SIZE = + "search_query_thread_core_pool_size"; /** - * Whether or not larger size icons are used for the pointer of mouse/trackpad for - * accessibility. - * (0 = false, 1 = true) + * The maximum size of the thread pool for suggestion queries in GlobalSearch. * @hide */ - public static final String ACCESSIBILITY_LARGE_POINTER_ICON = - "accessibility_large_pointer_icon"; - - private static final Validator ACCESSIBILITY_LARGE_POINTER_ICON_VALIDATOR = - BOOLEAN_VALIDATOR; - + public static final String SEARCH_QUERY_THREAD_MAX_POOL_SIZE = + "search_query_thread_max_pool_size"; /** - * The timeout for considering a press to be a long press in milliseconds. + * The size of the core thread pool for shortcut refreshing in GlobalSearch. * @hide */ - public static final String LONG_PRESS_TIMEOUT = "long_press_timeout"; - - private static final Validator LONG_PRESS_TIMEOUT_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; - + public static final String SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE = + "search_shortcut_refresh_core_pool_size"; /** - * The duration in milliseconds between the first tap's up event and the second tap's - * down event for an interaction to be considered part of the same multi-press. + * The maximum size of the thread pool for shortcut refreshing in GlobalSearch. * @hide */ - public static final String MULTI_PRESS_TIMEOUT = "multi_press_timeout"; - + public static final String SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE = + "search_shortcut_refresh_max_pool_size"; /** - * List of the enabled print services. - * - * N and beyond uses {@link #DISABLED_PRINT_SERVICES}. But this might be used in an upgrade - * from pre-N. - * + * The maximun time that excess threads in the GlobalSeach thread pools will + * wait before terminating. * @hide */ - public static final String ENABLED_PRINT_SERVICES = - "enabled_print_services"; - + public static final String SEARCH_THREAD_KEEPALIVE_SECONDS = + "search_thread_keepalive_seconds"; /** - * List of the disabled print services. - * + * The maximum number of concurrent suggestion queries to each source. * @hide */ - @TestApi - public static final String DISABLED_PRINT_SERVICES = - "disabled_print_services"; + public static final String SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT = + "search_per_source_concurrent_query_limit"; /** - * The saved value for WindowManagerService.setForcedDisplayDensity() - * formatted as a single integer representing DPI. If unset, then use - * the real display density. - * + * Whether or not alert sounds are played on StorageManagerService events. + * (0 = false, 1 = true) * @hide */ - public static final String DISPLAY_DENSITY_FORCED = "display_density_forced"; + public static final String MOUNT_PLAY_NOTIFICATION_SND = "mount_play_not_snd"; - /** - * Setting to always use the default text-to-speech settings regardless - * of the application settings. - * 1 = override application settings, - * 0 = use application settings (if specified). - * - * @deprecated The value of this setting is no longer respected by - * the framework text to speech APIs as of the Ice Cream Sandwich release. - */ - @Deprecated - public static final String TTS_USE_DEFAULTS = "tts_use_defaults"; + private static final Validator MOUNT_PLAY_NOTIFICATION_SND_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Default text-to-speech engine speech rate. 100 = 1x + * Whether or not UMS auto-starts on UMS host detection. (0 = false, 1 = true) + * @hide */ - public static final String TTS_DEFAULT_RATE = "tts_default_rate"; + public static final String MOUNT_UMS_AUTOSTART = "mount_ums_autostart"; - private static final Validator TTS_DEFAULT_RATE_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR; + private static final Validator MOUNT_UMS_AUTOSTART_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Default text-to-speech engine pitch. 100 = 1x + * Whether or not a notification is displayed on UMS host detection. (0 = false, 1 = true) + * @hide */ - public static final String TTS_DEFAULT_PITCH = "tts_default_pitch"; + public static final String MOUNT_UMS_PROMPT = "mount_ums_prompt"; - private static final Validator TTS_DEFAULT_PITCH_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR; + private static final Validator MOUNT_UMS_PROMPT_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Default text-to-speech engine. + * Whether or not a notification is displayed while UMS is enabled. (0 = false, 1 = true) + * @hide */ - public static final String TTS_DEFAULT_SYNTH = "tts_default_synth"; + public static final String MOUNT_UMS_NOTIFY_ENABLED = "mount_ums_notify_enabled"; - private static final Validator TTS_DEFAULT_SYNTH_VALIDATOR = PACKAGE_NAME_VALIDATOR; + private static final Validator MOUNT_UMS_NOTIFY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Default text-to-speech language. + * If nonzero, ANRs in invisible background processes bring up a dialog. + * Otherwise, the process will be silently killed. * - * @deprecated this setting is no longer in use, as of the Ice Cream - * Sandwich release. Apps should never need to read this setting directly, - * instead can query the TextToSpeech framework classes for the default - * locale. {@link TextToSpeech#getLanguage()}. + * Also prevents ANRs and crash dialogs from being suppressed. + * @hide */ - @Deprecated - public static final String TTS_DEFAULT_LANG = "tts_default_lang"; + public static final String ANR_SHOW_BACKGROUND = "anr_show_background"; /** - * Default text-to-speech country. - * - * @deprecated this setting is no longer in use, as of the Ice Cream - * Sandwich release. Apps should never need to read this setting directly, - * instead can query the TextToSpeech framework classes for the default - * locale. {@link TextToSpeech#getLanguage()}. + * If nonzero, crashes in foreground processes will bring up a dialog. + * Otherwise, the process will be silently killed. + * @hide */ - @Deprecated - public static final String TTS_DEFAULT_COUNTRY = "tts_default_country"; + public static final String SHOW_FIRST_CRASH_DIALOG_DEV_OPTION = + "show_first_crash_dialog_dev_option"; + + private static final Validator SHOW_FIRST_CRASH_DIALOG_DEV_OPTION_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Default text-to-speech locale variant. + * The {@link ComponentName} string of the service to be used as the voice recognition + * service. * - * @deprecated this setting is no longer in use, as of the Ice Cream - * Sandwich release. Apps should never need to read this setting directly, - * instead can query the TextToSpeech framework classes for the - * locale that is in use {@link TextToSpeech#getLanguage()}. + * @hide */ - @Deprecated - public static final String TTS_DEFAULT_VARIANT = "tts_default_variant"; + public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service"; /** - * Stores the default tts locales on a per engine basis. Stored as - * a comma seperated list of values, each value being of the form - * {@code engine_name:locale} for example, - * {@code com.foo.ttsengine:eng-USA,com.bar.ttsengine:esp-ESP}. This - * supersedes {@link #TTS_DEFAULT_LANG}, {@link #TTS_DEFAULT_COUNTRY} and - * {@link #TTS_DEFAULT_VARIANT}. Apps should never need to read this - * setting directly, and can query the TextToSpeech framework classes - * for the locale that is in use. + * Stores whether an user has consented to have apps verified through PAM. + * The value is boolean (1 or 0). * * @hide */ - public static final String TTS_DEFAULT_LOCALE = "tts_default_locale"; - - private static final Validator TTS_DEFAULT_LOCALE_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - if (value == null || value.length() == 0) { - return false; - } - String[] ttsLocales = value.split(","); - boolean valid = true; - for (String ttsLocale : ttsLocales) { - String[] parts = ttsLocale.split(":"); - valid |= ((parts.length == 2) - && (parts[0].length() > 0) - && ANY_STRING_VALIDATOR.validate(parts[0]) - && LOCALE_VALIDATOR.validate(parts[1])); - } - return valid; - } - }; + public static final String PACKAGE_VERIFIER_USER_CONSENT = + "package_verifier_user_consent"; /** - * Space delimited list of plugin packages that are enabled. + * The {@link ComponentName} string of the selected spell checker service which is + * one of the services managed by the text service manager. + * + * @hide */ - public static final String TTS_ENABLED_PLUGINS = "tts_enabled_plugins"; + public static final String SELECTED_SPELL_CHECKER = "selected_spell_checker"; - private static final Validator TTS_ENABLED_PLUGINS_VALIDATOR = - new SettingsValidators.PackageNameListValidator(" "); + private static final Validator SELECTED_SPELL_CHECKER_VALIDATOR = COMPONENT_NAME_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON} - * instead. + * The {@link ComponentName} string of the selected subtype of the selected spell checker + * service which is one of the services managed by the text service manager. + * + * @hide */ - @Deprecated - public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = - Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; + public static final String SELECTED_SPELL_CHECKER_SUBTYPE = + "selected_spell_checker_subtype"; - private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = - BOOLEAN_VALIDATOR; + private static final Validator SELECTED_SPELL_CHECKER_SUBTYPE_VALIDATOR = + COMPONENT_NAME_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} - * instead. + * Whether spell checker is enabled or not. + * + * @hide */ - @Deprecated - public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = - Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY; + public static final String SPELL_CHECKER_ENABLED = "spell_checker_enabled"; - private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + private static final Validator SPELL_CHECKER_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT} - * instead. + * What happens when the user presses the Power button while in-call + * and the screen is on.
+ * Values:
+ * 1 - The Power button turns off the screen and locks the device. (Default behavior)
+ * 2 - The Power button hangs up the current call.
+ * + * @hide */ - @Deprecated - public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = - Global.WIFI_NUM_OPEN_NETWORKS_KEPT; + public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior"; - private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + private static final Validator INCALL_POWER_BUTTON_BEHAVIOR_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[]{"1", "2"}); /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_ON} - * instead. + * INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen". + * @hide */ - @Deprecated - public static final String WIFI_ON = Global.WIFI_ON; + public static final int INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF = 0x1; /** - * The acceptable packet loss percentage (range 0 - 100) before trying - * another AP on the same network. - * @deprecated This setting is not used. + * INCALL_POWER_BUTTON_BEHAVIOR value for "hang up". + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = - "wifi_watchdog_acceptable_packet_loss_percentage"; + public static final int INCALL_POWER_BUTTON_BEHAVIOR_HANGUP = 0x2; /** - * The number of access points required for a network in order for the - * watchdog to monitor it. - * @deprecated This setting is not used. + * INCALL_POWER_BUTTON_BEHAVIOR default value. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count"; + public static final int INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT = + INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF; /** - * The delay between background checks. - * @deprecated This setting is not used. + * What happens when the user presses the Back button while in-call + * and the screen is on.
+ * Values:
+ * 0 - The Back buttons does nothing different.
+ * 1 - The Back button hangs up the current call.
+ * + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = - "wifi_watchdog_background_check_delay_ms"; + public static final String INCALL_BACK_BUTTON_BEHAVIOR = "incall_back_button_behavior"; /** - * Whether the Wi-Fi watchdog is enabled for background checking even - * after it thinks the user has connected to a good access point. - * @deprecated This setting is not used. + * INCALL_BACK_BUTTON_BEHAVIOR value for no action. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = - "wifi_watchdog_background_check_enabled"; + public static final int INCALL_BACK_BUTTON_BEHAVIOR_NONE = 0x0; /** - * The timeout for a background ping - * @deprecated This setting is not used. + * INCALL_BACK_BUTTON_BEHAVIOR value for "hang up". + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = - "wifi_watchdog_background_check_timeout_ms"; + public static final int INCALL_BACK_BUTTON_BEHAVIOR_HANGUP = 0x1; /** - * The number of initial pings to perform that *may* be ignored if they - * fail. Again, if these fail, they will *not* be used in packet loss - * calculation. For example, one network always seemed to time out for - * the first couple pings, so this is set to 3 by default. - * @deprecated This setting is not used. + * INCALL_POWER_BUTTON_BEHAVIOR default value. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = - "wifi_watchdog_initial_ignored_ping_count"; + public static final int INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT = + INCALL_BACK_BUTTON_BEHAVIOR_NONE; /** - * The maximum number of access points (per network) to attempt to test. - * If this number is reached, the watchdog will no longer monitor the - * initial connection state for the network. This is a safeguard for - * networks containing multiple APs whose DNS does not respond to pings. - * @deprecated This setting is not used. + * Whether the device should wake when the wake gesture sensor detects motion. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks"; + public static final String WAKE_GESTURE_ENABLED = "wake_gesture_enabled"; + + private static final Validator WAKE_GESTURE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead + * Disable power menu on secure lock screens + * + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on"; + public static final String LOCK_POWER_MENU_DISABLED = "lockscreen_power_menu_disabled"; + + private static final Validator LOCK_POWER_MENU_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * A comma-separated list of SSIDs for which the Wi-Fi watchdog should be enabled. - * @deprecated This setting is not used. + * Whether the device should doze if configured. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list"; + public static final String DOZE_ENABLED = "doze_enabled"; + + private static final Validator DOZE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * The number of pings to test if an access point is a good connection. - * @deprecated This setting is not used. + * Whether doze should be always on. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count"; + public static final String DOZE_ALWAYS_ON = "doze_always_on"; /** - * The delay between pings. - * @deprecated This setting is not used. + * Whether the device should pulse on pick up gesture. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms"; + public static final String DOZE_PULSE_ON_PICK_UP = "doze_pulse_on_pick_up"; + + private static final Validator DOZE_PULSE_ON_PICK_UP_VALIDATOR = BOOLEAN_VALIDATOR; /** - * The timeout per ping. - * @deprecated This setting is not used. + * Whether the device should pulse on long press gesture. + * @hide */ - @Deprecated - public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms"; + public static final String DOZE_PULSE_ON_LONG_PRESS = "doze_pulse_on_long_press"; /** - * @deprecated Use - * {@link android.provider.Settings.Global#WIFI_MAX_DHCP_RETRY_COUNT} instead + * Whether the device should pulse on double tap gesture. + * @hide */ - @Deprecated - public static final String WIFI_MAX_DHCP_RETRY_COUNT = Global.WIFI_MAX_DHCP_RETRY_COUNT; + public static final String DOZE_PULSE_ON_DOUBLE_TAP = "doze_pulse_on_double_tap"; + + private static final Validator DOZE_PULSE_ON_DOUBLE_TAP_VALIDATOR = BOOLEAN_VALIDATOR; /** - * @deprecated Use - * {@link android.provider.Settings.Global#WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS} instead + * The current night mode that has been selected by the user. Owned + * and controlled by UiModeManagerService. Constants are as per + * UiModeManager. + * @hide */ - @Deprecated - public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = - Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS; + public static final String UI_NIGHT_MODE = "ui_night_mode"; /** - * The number of milliseconds to hold on to a PendingIntent based request. This delay gives - * the receivers of the PendingIntent an opportunity to make a new network request before - * the Network satisfying the request is potentially removed. + * The current device UI theme mode effect SystemUI and Launcher.
+ * Values:
+ * 0 - The mode that theme will controlled by wallpaper color.
+ * 1 - The mode that will always light theme.
+ * 2 - The mode that will always dark theme.
* * @hide */ - public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS = - "connectivity_release_pending_intent_delay_ms"; + public static final String THEME_MODE = "theme_mode"; /** - * Whether background data usage is allowed. - * - * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, - * availability of background data depends on several - * combined factors. When background data is unavailable, - * {@link ConnectivityManager#getActiveNetworkInfo()} will - * now appear disconnected. + * THEME_MODE value for wallpaper mode. + * @hide */ - @Deprecated - public static final String BACKGROUND_DATA = "background_data"; + public static final int THEME_MODE_WALLPAPER = 0; /** - * Origins for which browsers should allow geolocation by default. - * The value is a space-separated list of origins. + * THEME_MODE value for light theme mode. + * @hide */ - public static final String ALLOWED_GEOLOCATION_ORIGINS - = "allowed_geolocation_origins"; + public static final int THEME_MODE_LIGHT = 1; /** - * The preferred TTY mode 0 = TTy Off, CDMA default - * 1 = TTY Full - * 2 = TTY HCO - * 3 = TTY VCO + * THEME_MODE value for dark theme mode. * @hide */ - public static final String PREFERRED_TTY_MODE = - "preferred_tty_mode"; + public static final int THEME_MODE_DARK = 2; - private static final Validator PREFERRED_TTY_MODE_VALIDATOR = - new SettingsValidators.DiscreteValueValidator(new String[]{"0", "1", "2", "3"}); + /** + * Whether screensavers are enabled. + * @hide + */ + public static final String SCREENSAVER_ENABLED = "screensaver_enabled"; + + private static final Validator SCREENSAVER_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Whether the enhanced voice privacy mode is enabled. - * 0 = normal voice privacy - * 1 = enhanced voice privacy + * The user's chosen screensaver components. + * + * These will be launched by the PhoneWindowManager after a timeout when not on + * battery, or upon dock insertion (if SCREENSAVER_ACTIVATE_ON_DOCK is set to 1). * @hide */ - public static final String ENHANCED_VOICE_PRIVACY_ENABLED = "enhanced_voice_privacy_enabled"; + public static final String SCREENSAVER_COMPONENTS = "screensaver_components"; - private static final Validator ENHANCED_VOICE_PRIVACY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator SCREENSAVER_COMPONENTS_VALIDATOR = + new SettingsValidators.ComponentNameListValidator(","); /** - * Whether the TTY mode mode is enabled. - * 0 = disabled - * 1 = enabled + * If screensavers are enabled, whether the screensaver should be automatically launched + * when the device is inserted into a (desk) dock. * @hide */ - public static final String TTY_MODE_ENABLED = "tty_mode_enabled"; + public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock"; - private static final Validator TTY_MODE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator SCREENSAVER_ACTIVATE_ON_DOCK_VALIDATOR = BOOLEAN_VALIDATOR; /** - * User-selected RTT mode. When on, outgoing and incoming calls will be answered as RTT - * calls when supported by the device and carrier. Boolean value. - * 0 = OFF - * 1 = ON + * If screensavers are enabled, whether the screensaver should be automatically launched + * when the screen times out when not on battery. + * @hide */ - public static final String RTT_CALLING_MODE = "rtt_calling_mode"; + public static final String SCREENSAVER_ACTIVATE_ON_SLEEP = "screensaver_activate_on_sleep"; - private static final Validator RTT_CALLING_MODE_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator SCREENSAVER_ACTIVATE_ON_SLEEP_VALIDATOR = BOOLEAN_VALIDATOR; /** + * If screensavers are enabled, the default screensaver component. + * @hide + */ + public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component"; + /** - * Controls whether settings backup is enabled. - * Type: int ( 0 = disabled, 1 = enabled ) + * The default NFC payment component * @hide */ - public static final String BACKUP_ENABLED = "backup_enabled"; + public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component"; + + private static final Validator NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR = + COMPONENT_NAME_VALIDATOR; /** - * Controls whether application data is automatically restored from backup - * at install time. - * Type: int ( 0 = disabled, 1 = enabled ) + * Whether NFC payment is handled by the foreground application or a default. * @hide */ - public static final String BACKUP_AUTO_RESTORE = "backup_auto_restore"; + public static final String NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground"; /** - * Indicates whether settings backup has been fully provisioned. - * Type: int ( 0 = unprovisioned, 1 = fully provisioned ) + * Specifies the package name currently configured to be the primary sms application * @hide */ - public static final String BACKUP_PROVISIONED = "backup_provisioned"; + public static final String SMS_DEFAULT_APPLICATION = "sms_default_application"; /** - * Component of the transport to use for backup/restore. + * Specifies the package name currently configured to be the default dialer application * @hide */ - public static final String BACKUP_TRANSPORT = "backup_transport"; + public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application"; /** - * Version for which the setup wizard was last shown. Bumped for - * each release when there is new setup information to show. + * Specifies the package name currently configured to be the emergency assistance application + * + * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE + * * @hide */ - public static final String LAST_SETUP_SHOWN = "last_setup_shown"; + public static final String EMERGENCY_ASSISTANCE_APPLICATION = "emergency_assistance_application"; /** - * The interval in milliseconds after which Wi-Fi is considered idle. - * When idle, it is possible for the device to be switched from Wi-Fi to - * the mobile data network. + * Specifies whether the current app context on scren (assist data) will be sent to the + * assist application (active voice interaction service). + * * @hide - * @deprecated Use {@link android.provider.Settings.Global#WIFI_IDLE_MS} - * instead. */ - @Deprecated - public static final String WIFI_IDLE_MS = Global.WIFI_IDLE_MS; + public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled"; /** - * The global search provider chosen by the user (if multiple global - * search providers are installed). This will be the provider returned - * by {@link SearchManager#getGlobalSearchActivity()} if it's still - * installed. This setting is stored as a flattened component name as - * per {@link ComponentName#flattenToString()}. + * Specifies whether a screenshot of the screen contents will be sent to the assist + * application (active voice interaction service). * * @hide */ - public static final String SEARCH_GLOBAL_SEARCH_ACTIVITY = - "search_global_search_activity"; + public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled"; /** - * The number of promoted sources in GlobalSearch. + * Specifies whether the screen will show an animation if screen contents are sent to the + * assist application (active voice interaction service). + * + * Note that the disclosure will be forced for third-party assistants or if the device + * does not support disabling it. + * * @hide */ - public static final String SEARCH_NUM_PROMOTED_SOURCES = "search_num_promoted_sources"; + public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled"; + /** - * The maximum number of suggestions returned by GlobalSearch. + * Control if rotation suggestions are sent to System UI when in rotation locked mode. + * Done to enable screen rotation while the the screen rotation is locked. Enabling will + * poll the accelerometer in rotation locked mode. + * + * If 0, then rotation suggestions are not sent to System UI. If 1, suggestions are sent. + * * @hide */ - public static final String SEARCH_MAX_RESULTS_TO_DISPLAY = "search_max_results_to_display"; + + public static final String SHOW_ROTATION_SUGGESTIONS = "show_rotation_suggestions"; + /** - * The number of suggestions GlobalSearch will ask each non-web search source for. + * The disabled state of SHOW_ROTATION_SUGGESTIONS. * @hide */ - public static final String SEARCH_MAX_RESULTS_PER_SOURCE = "search_max_results_per_source"; + public static final int SHOW_ROTATION_SUGGESTIONS_DISABLED = 0x0; + /** - * The number of suggestions the GlobalSearch will ask the web search source for. + * The enabled state of SHOW_ROTATION_SUGGESTIONS. * @hide */ - public static final String SEARCH_WEB_RESULTS_OVERRIDE_LIMIT = - "search_web_results_override_limit"; + public static final int SHOW_ROTATION_SUGGESTIONS_ENABLED = 0x1; + /** - * The number of milliseconds that GlobalSearch will wait for suggestions from - * promoted sources before continuing with all other sources. + * The default state of SHOW_ROTATION_SUGGESTIONS. * @hide */ - public static final String SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS = - "search_promoted_source_deadline_millis"; + public static final int SHOW_ROTATION_SUGGESTIONS_DEFAULT = + SHOW_ROTATION_SUGGESTIONS_ENABLED; + /** - * The number of milliseconds before GlobalSearch aborts search suggesiton queries. + * The number of accepted rotation suggestions. Used to determine if the user has been + * introduced to rotation suggestions. * @hide */ - public static final String SEARCH_SOURCE_TIMEOUT_MILLIS = "search_source_timeout_millis"; + public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED = + "num_rotation_suggestions_accepted"; + /** - * The maximum number of milliseconds that GlobalSearch shows the previous results - * after receiving a new query. + * Read only list of the service components that the current user has explicitly allowed to + * see and assist with all of the user's notifications. + * + * @deprecated Use + * {@link NotificationManager#isNotificationListenerAccessGranted(ComponentName)}. * @hide */ - public static final String SEARCH_PREFILL_MILLIS = "search_prefill_millis"; + @Deprecated + public static final String ENABLED_NOTIFICATION_ASSISTANT = + "enabled_notification_assistant"; + + private static final Validator ENABLED_NOTIFICATION_ASSISTANT_VALIDATOR = + new SettingsValidators.ComponentNameListValidator(":"); + /** - * The maximum age of log data used for shortcuts in GlobalSearch. + * Read only list of the service components that the current user has explicitly allowed to + * see all of the user's notifications, separated by ':'. + * * @hide + * @deprecated Use + * {@link NotificationManager#isNotificationAssistantAccessGranted(ComponentName)}. */ - public static final String SEARCH_MAX_STAT_AGE_MILLIS = "search_max_stat_age_millis"; + @Deprecated + public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners"; + + private static final Validator ENABLED_NOTIFICATION_LISTENERS_VALIDATOR = + new SettingsValidators.ComponentNameListValidator(":"); + /** - * The maximum age of log data used for source ranking in GlobalSearch. + * Read only list of the packages that the current user has explicitly allowed to + * manage do not disturb, separated by ':'. + * + * @deprecated Use {@link NotificationManager#isNotificationPolicyAccessGranted()}. * @hide */ - public static final String SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS = - "search_max_source_event_age_millis"; + @Deprecated + @TestApi + public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = + "enabled_notification_policy_access_packages"; + + private static final Validator ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR = + new SettingsValidators.PackageNameListValidator(":"); + /** - * The minimum number of impressions needed to rank a source in GlobalSearch. + * Defines whether managed profile ringtones should be synced from it's parent profile + *

+ * 0 = ringtones are not synced + * 1 = ringtones are synced from the profile's parent (default) + *

+ * This value is only used for managed profiles. * @hide */ - public static final String SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING = - "search_min_impressions_for_source_ranking"; + @TestApi + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds"; + + private static final Validator SYNC_PARENT_SOUNDS_VALIDATOR = BOOLEAN_VALIDATOR; + + /** @hide */ + public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations"; + /** - * The minimum number of clicks needed to rank a source in GlobalSearch. + * This is the query URI for finding a print service to install. + * * @hide */ - public static final String SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING = - "search_min_clicks_for_source_ranking"; + public static final String PRINT_SERVICE_SEARCH_URI = "print_service_search_uri"; + /** - * The maximum number of shortcuts shown by GlobalSearch. + * This is the query URI for finding a NFC payment service to install. + * * @hide */ - public static final String SEARCH_MAX_SHORTCUTS_RETURNED = "search_max_shortcuts_returned"; + public static final String PAYMENT_SERVICE_SEARCH_URI = "payment_service_search_uri"; + /** - * The size of the core thread pool for suggestion queries in GlobalSearch. + * This is the query URI for finding a auto fill service to install. + * * @hide */ - public static final String SEARCH_QUERY_THREAD_CORE_POOL_SIZE = - "search_query_thread_core_pool_size"; + public static final String AUTOFILL_SERVICE_SEARCH_URI = "autofill_service_search_uri"; + /** - * The maximum size of the thread pool for suggestion queries in GlobalSearch. - * @hide + * If enabled, apps should try to skip any introductory hints on first launch. This might + * apply to users that are already familiar with the environment or temporary users. + *

+ * Type : int (0 to show hints, 1 to skip showing hints) */ - public static final String SEARCH_QUERY_THREAD_MAX_POOL_SIZE = - "search_query_thread_max_pool_size"; + public static final String SKIP_FIRST_USE_HINTS = "skip_first_use_hints"; + /** - * The size of the core thread pool for shortcut refreshing in GlobalSearch. + * Persisted playback time after a user confirmation of an unsafe volume level. + * * @hide */ - public static final String SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE = - "search_shortcut_refresh_core_pool_size"; + public static final String UNSAFE_VOLUME_MUSIC_ACTIVE_MS = "unsafe_volume_music_active_ms"; + /** - * The maximum size of the thread pool for shortcut refreshing in GlobalSearch. + * This preference enables notification display on the lockscreen. * @hide */ - public static final String SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE = - "search_shortcut_refresh_max_pool_size"; + public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = + "lock_screen_show_notifications"; + /** - * The maximun time that excess threads in the GlobalSeach thread pools will - * wait before terminating. + * List of TV inputs that are currently hidden. This is a string + * containing the IDs of all hidden TV inputs. Each ID is encoded by + * {@link android.net.Uri#encode(String)} and separated by ':'. * @hide */ - public static final String SEARCH_THREAD_KEEPALIVE_SECONDS = - "search_thread_keepalive_seconds"; + public static final String TV_INPUT_HIDDEN_INPUTS = "tv_input_hidden_inputs"; + /** - * The maximum number of concurrent suggestion queries to each source. + * List of custom TV input labels. This is a string containing + * pairs. TV input id and custom name are encoded by {@link android.net.Uri#encode(String)} + * and separated by ','. Each pair is separated by ':'. * @hide */ - public static final String SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT = - "search_per_source_concurrent_query_limit"; + public static final String TV_INPUT_CUSTOM_LABELS = "tv_input_custom_labels"; /** - * Whether or not alert sounds are played on StorageManagerService events. - * (0 = false, 1 = true) + * Whether automatic routing of system audio to USB audio peripheral is disabled. + * The value is boolean (1 or 0), where 1 means automatic routing is disabled, + * and 0 means automatic routing is enabled. + * * @hide */ - public static final String MOUNT_PLAY_NOTIFICATION_SND = "mount_play_not_snd"; - - private static final Validator MOUNT_PLAY_NOTIFICATION_SND_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED = + "usb_audio_automatic_routing_disabled"; /** - * Whether or not UMS auto-starts on UMS host detection. (0 = false, 1 = true) + * The timeout in milliseconds before the device fully goes to sleep after + * a period of inactivity. This value sets an upper bound on how long the device + * will stay awake or dreaming without user activity. It should generally + * be longer than {@link Settings.System#SCREEN_OFF_TIMEOUT} as otherwise the device + * will sleep before it ever has a chance to dream. + *

+ * Use -1 to disable this timeout. + *

+ * * @hide */ - public static final String MOUNT_UMS_AUTOSTART = "mount_ums_autostart"; + public static final String SLEEP_TIMEOUT = "sleep_timeout"; - private static final Validator MOUNT_UMS_AUTOSTART_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator SLEEP_TIMEOUT_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(-1, Integer.MAX_VALUE); /** - * Whether or not a notification is displayed on UMS host detection. (0 = false, 1 = true) + * Controls whether double tap to wake is enabled. * @hide */ - public static final String MOUNT_UMS_PROMPT = "mount_ums_prompt"; + public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake"; - private static final Validator MOUNT_UMS_PROMPT_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator DOUBLE_TAP_TO_WAKE_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Whether or not a notification is displayed while UMS is enabled. (0 = false, 1 = true) + * The current assistant component. It could be a voice interaction service, + * or an activity that handles ACTION_ASSIST, or empty which means using the default + * handling. + * * @hide */ - public static final String MOUNT_UMS_NOTIFY_ENABLED = "mount_ums_notify_enabled"; - - private static final Validator MOUNT_UMS_NOTIFY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String ASSISTANT = "assistant"; /** - * If nonzero, ANRs in invisible background processes bring up a dialog. - * Otherwise, the process will be silently killed. + * Whether the camera launch gesture should be disabled. * - * Also prevents ANRs and crash dialogs from being suppressed. * @hide */ - public static final String ANR_SHOW_BACKGROUND = "anr_show_background"; + public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled"; + + private static final Validator CAMERA_GESTURE_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * If nonzero, crashes in foreground processes will bring up a dialog. - * Otherwise, the process will be silently killed. + * Whether the camera launch gesture to double tap the power button when the screen is off + * should be disabled. + * * @hide */ - public static final String SHOW_FIRST_CRASH_DIALOG_DEV_OPTION = - "show_first_crash_dialog_dev_option"; + public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED = + "camera_double_tap_power_gesture_disabled"; - private static final Validator SHOW_FIRST_CRASH_DIALOG_DEV_OPTION_VALIDATOR = + private static final Validator CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * The {@link ComponentName} string of the service to be used as the voice recognition - * service. + * Whether the torch launch gesture to double tap or long press the power button when the + * screen is off should be enabled. * + * 0: disabled + * 1: double tap power for torch + * 2: long tap power for torch * @hide */ - public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service"; + public static final String TORCH_POWER_BUTTON_GESTURE = + "torch_power_button_gesture"; + + private static final Validator TORCH_POWER_BUTTON_GESTURE_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Stores whether an user has consented to have apps verified through PAM. - * The value is boolean (1 or 0). + * Whether the camera double twist gesture to flip between front and back mode should be + * enabled. * * @hide */ - public static final String PACKAGE_VERIFIER_USER_CONSENT = - "package_verifier_user_consent"; + public static final String CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED = + "camera_double_twist_to_flip_enabled"; + + private static final Validator CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * The {@link ComponentName} string of the selected spell checker service which is - * one of the services managed by the text service manager. + * Whether the swipe up gesture to switch apps should be enabled. * * @hide */ - public static final String SELECTED_SPELL_CHECKER = "selected_spell_checker"; + public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED = + "swipe_up_to_switch_apps_enabled"; - private static final Validator SELECTED_SPELL_CHECKER_VALIDATOR = COMPONENT_NAME_VALIDATOR; + private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * The {@link ComponentName} string of the selected subtype of the selected spell checker - * service which is one of the services managed by the text service manager. + * Whether or not the smart camera lift trigger that launches the camera when the user moves + * the phone into a position for taking photos should be enabled. * * @hide */ - public static final String SELECTED_SPELL_CHECKER_SUBTYPE = - "selected_spell_checker_subtype"; + public static final String CAMERA_LIFT_TRIGGER_ENABLED = "camera_lift_trigger_enabled"; - private static final Validator SELECTED_SPELL_CHECKER_SUBTYPE_VALIDATOR = - COMPONENT_NAME_VALIDATOR; + /** + * The default enable state of the camera lift trigger. + * + * @hide + */ + public static final int CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT = 1; /** - * Whether spell checker is enabled or not. + * Whether the assist gesture should be enabled. * * @hide */ - public static final String SPELL_CHECKER_ENABLED = "spell_checker_enabled"; + public static final String ASSIST_GESTURE_ENABLED = "assist_gesture_enabled"; - private static final Validator SPELL_CHECKER_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator ASSIST_GESTURE_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * What happens when the user presses the Power button while in-call - * and the screen is on.
- * Values:
- * 1 - The Power button turns off the screen and locks the device. (Default behavior)
- * 2 - The Power button hangs up the current call.
+ * Sensitivity control for the assist gesture. * * @hide */ - public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior"; - - private static final Validator INCALL_POWER_BUTTON_BEHAVIOR_VALIDATOR = - new SettingsValidators.DiscreteValueValidator(new String[]{"1", "2"}); + public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity"; /** - * INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen". + * Whether the assist gesture should silence alerts. + * * @hide */ - public static final int INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF = 0x1; + public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED = + "assist_gesture_silence_alerts_enabled"; + + private static final Validator ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * INCALL_POWER_BUTTON_BEHAVIOR value for "hang up". + * Whether the assist gesture should wake the phone. + * * @hide */ - public static final int INCALL_POWER_BUTTON_BEHAVIOR_HANGUP = 0x2; + public static final String ASSIST_GESTURE_WAKE_ENABLED = + "assist_gesture_wake_enabled"; - /** - * INCALL_POWER_BUTTON_BEHAVIOR default value. - * @hide - */ - public static final int INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT = - INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF; + private static final Validator ASSIST_GESTURE_WAKE_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * What happens when the user presses the Back button while in-call - * and the screen is on.
- * Values:
- * 0 - The Back buttons does nothing different.
- * 1 - The Back button hangs up the current call.
+ * Whether Assist Gesture Deferred Setup has been completed * * @hide */ - public static final String INCALL_BACK_BUTTON_BEHAVIOR = "incall_back_button_behavior"; + public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete"; /** - * INCALL_BACK_BUTTON_BEHAVIOR value for no action. + * Control whether Night display is currently activated. * @hide */ - public static final int INCALL_BACK_BUTTON_BEHAVIOR_NONE = 0x0; + public static final String NIGHT_DISPLAY_ACTIVATED = "night_display_activated"; /** - * INCALL_BACK_BUTTON_BEHAVIOR value for "hang up". + * Control whether Night display will automatically activate/deactivate. * @hide */ - public static final int INCALL_BACK_BUTTON_BEHAVIOR_HANGUP = 0x1; + public static final String NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode"; + + private static final Validator NIGHT_DISPLAY_AUTO_MODE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); /** - * INCALL_POWER_BUTTON_BEHAVIOR default value. + * Control the color temperature of Night Display, represented in Kelvin. * @hide */ - public static final int INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT = - INCALL_BACK_BUTTON_BEHAVIOR_NONE; + public static final String NIGHT_DISPLAY_COLOR_TEMPERATURE = + "night_display_color_temperature"; + + private static final Validator NIGHT_DISPLAY_COLOR_TEMPERATURE_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Whether the device should wake when the wake gesture sensor detects motion. + * Custom time when Night display is scheduled to activate. + * Represented as milliseconds from midnight (e.g. 79200000 == 10pm). * @hide */ - public static final String WAKE_GESTURE_ENABLED = "wake_gesture_enabled"; + public static final String NIGHT_DISPLAY_CUSTOM_START_TIME = + "night_display_custom_start_time"; - private static final Validator WAKE_GESTURE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator NIGHT_DISPLAY_CUSTOM_START_TIME_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Whether the device should doze if configured. + * Custom time when Night display is scheduled to deactivate. + * Represented as milliseconds from midnight (e.g. 21600000 == 6am). * @hide */ - public static final String DOZE_ENABLED = "doze_enabled"; + public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time"; - private static final Validator DOZE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator NIGHT_DISPLAY_CUSTOM_END_TIME_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Whether doze should be always on. + * A String representing the LocalDateTime when Night display was last activated. Use to + * decide whether to apply the current activated state after a reboot or user change. In + * legacy cases, this is represented by the time in milliseconds (since epoch). * @hide */ - public static final String DOZE_ALWAYS_ON = "doze_always_on"; + public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME = + "night_display_last_activated_time"; /** - * Whether the device should pulse on pick up gesture. + * Names of the service components that the current user has explicitly allowed to + * be a VR mode listener, separated by ':'. + * * @hide */ - public static final String DOZE_PULSE_ON_PICK_UP = "doze_pulse_on_pick_up"; + public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners"; - private static final Validator DOZE_PULSE_ON_PICK_UP_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator ENABLED_VR_LISTENERS_VALIDATOR = + new SettingsValidators.ComponentNameListValidator(":"); /** - * Whether the device should pulse on long press gesture. + * Behavior of the display while in VR mode. + * + * One of {@link #VR_DISPLAY_MODE_LOW_PERSISTENCE} or {@link #VR_DISPLAY_MODE_OFF}. + * * @hide */ - public static final String DOZE_PULSE_ON_LONG_PRESS = "doze_pulse_on_long_press"; + public static final String VR_DISPLAY_MODE = "vr_display_mode"; + + private static final Validator VR_DISPLAY_MODE_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[]{"0", "1"}); /** - * Whether the device should pulse on double tap gesture. + * Disable hw buttons - actions, brightness, haptic feedback, overflow menu * @hide */ - public static final String DOZE_PULSE_ON_DOUBLE_TAP = "doze_pulse_on_double_tap"; - - private static final Validator DOZE_PULSE_ON_DOUBLE_TAP_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String HARDWARE_KEYS_DISABLE = "hardware_keys_disable"; /** * The current night mode that has been selected by the user. Owned @@ -7113,820 +9199,715 @@ public boolean validate(@Nullable String value) { * UiModeManager. * @hide */ - public static final String UI_NIGHT_MODE = "ui_night_mode"; + public static final int VR_DISPLAY_MODE_LOW_PERSISTENCE = 0; /** - * The current device UI theme mode effect SystemUI and Launcher.
- * Values:
- * 0 - The mode that theme will controlled by wallpaper color.
- * 1 - The mode that will always light theme.
- * 2 - The mode that will always dark theme.
+ * Do not alter the display persistence while the system is in VR mode. + * + * @see PackageManager#FEATURE_VR_MODE_HIGH_PERFORMANCE + * + * @hide. + */ + public static final int VR_DISPLAY_MODE_OFF = 1; + + /** + * Whether CarrierAppUtils#disableCarrierAppsUntilPrivileged has been executed at least + * once. + * + *

This is used to ensure that we only take one pass which will disable apps that are not + * privileged (if any). From then on, we only want to enable apps (when a matching SIM is + * inserted), to avoid disabling an app that the user might actively be using. + * + *

Will be set to 1 once executed. * * @hide */ - public static final String THEME_MODE = "theme_mode"; + public static final String CARRIER_APPS_HANDLED = "carrier_apps_handled"; /** - * THEME_MODE value for wallpaper mode. + * Whether parent user can access remote contact in managed profile. + * * @hide */ - public static final int THEME_MODE_WALLPAPER = 0; + public static final String MANAGED_PROFILE_CONTACT_REMOTE_SEARCH = + "managed_profile_contact_remote_search"; /** - * THEME_MODE value for light theme mode. + * Enable face auto unlock on secure lock screens + * * @hide */ - public static final int THEME_MODE_LIGHT = 1; + public static final String FACE_AUTO_UNLOCK = "face_auto_unlock"; /** - * THEME_MODE value for dark theme mode. + * Whether or not the automatic storage manager is enabled and should run on the device. + * * @hide */ - public static final int THEME_MODE_DARK = 2; + public static final String AUTOMATIC_STORAGE_MANAGER_ENABLED = + "automatic_storage_manager_enabled"; /** - * Whether screensavers are enabled. + * How many days of information for the automatic storage manager to retain on the device. + * * @hide */ - public static final String SCREENSAVER_ENABLED = "screensaver_enabled"; + public static final String AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN = + "automatic_storage_manager_days_to_retain"; - private static final Validator SCREENSAVER_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + private static final Validator AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * The user's chosen screensaver components. + * Default number of days of information for the automatic storage manager to retain. * - * These will be launched by the PhoneWindowManager after a timeout when not on - * battery, or upon dock insertion (if SCREENSAVER_ACTIVATE_ON_DOCK is set to 1). * @hide */ - public static final String SCREENSAVER_COMPONENTS = "screensaver_components"; - - private static final Validator SCREENSAVER_COMPONENTS_VALIDATOR = - new SettingsValidators.ComponentNameListValidator(","); + public static final int AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_DEFAULT = 90; /** - * If screensavers are enabled, whether the screensaver should be automatically launched - * when the device is inserted into a (desk) dock. + * How many bytes the automatic storage manager has cleared out. + * * @hide */ - public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock"; + public static final String AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED = + "automatic_storage_manager_bytes_cleared"; - private static final Validator SCREENSAVER_ACTIVATE_ON_DOCK_VALIDATOR = BOOLEAN_VALIDATOR; /** - * If screensavers are enabled, whether the screensaver should be automatically launched - * when the screen times out when not on battery. + * Last run time for the automatic storage manager. + * * @hide */ - public static final String SCREENSAVER_ACTIVATE_ON_SLEEP = "screensaver_activate_on_sleep"; + public static final String AUTOMATIC_STORAGE_MANAGER_LAST_RUN = + "automatic_storage_manager_last_run"; - private static final Validator SCREENSAVER_ACTIVATE_ON_SLEEP_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * If the automatic storage manager has been disabled by policy. Note that this doesn't + * mean that the automatic storage manager is prevented from being re-enabled -- this only + * means that it was turned off by policy at least once. + * + * @hide + */ + public static final String AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY = + "automatic_storage_manager_turned_off_by_policy"; /** - * If screensavers are enabled, the default screensaver component. + * Whether SystemUI navigation keys is enabled. * @hide */ - public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component"; + public static final String SYSTEM_NAVIGATION_KEYS_ENABLED = + "system_navigation_keys_enabled"; + + private static final Validator SYSTEM_NAVIGATION_KEYS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; /** - * The default NFC payment component + * Wheter to dismiss notifications on fingerprint left and right swipe action * @hide */ - public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component"; + public static final String FP_SWIPE_TO_DISMISS_NOTIFICATIONS = "fp_swipe_to_dismiss_notifications"; - private static final Validator NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR = - COMPONENT_NAME_VALIDATOR; + private static final Validator FP_SWIPE_TO_DISMISS_NOTIFICATIONS_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Whether NFC payment is handled by the foreground application or a default. + * Holds comma separated list of ordering of QS tiles. * @hide */ - public static final String NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground"; + public static final String QS_TILES = "sysui_qs_tiles"; + + private static final Validator QS_TILES_VALIDATOR = new Validator() { + @Override + public boolean validate(@Nullable String value) { + if (value == null) { + return false; + } + String[] tiles = value.split(","); + boolean valid = true; + for (String tile : tiles) { + // tile can be any non-empty string as specified by OEM + valid |= ((tile.length() > 0) && ANY_STRING_VALIDATOR.validate(tile)); + } + return valid; + } + }; /** - * Specifies the package name currently configured to be the primary sms application + * Specifies whether the web action API is enabled. + * * @hide */ - public static final String SMS_DEFAULT_APPLICATION = "sms_default_application"; + @SystemApi + public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled"; /** - * Specifies the package name currently configured to be the default dialer application + * Has this pairable device been paired or upgraded from a previously paired system. * @hide */ - public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application"; + public static final String DEVICE_PAIRED = "device_paired"; /** - * Specifies the package name currently configured to be the emergency assistance application - * - * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE + * Integer state indicating whether package verifier is enabled. + * TODO(b/34259924): Remove this setting. * * @hide */ - public static final String EMERGENCY_ASSISTANCE_APPLICATION = "emergency_assistance_application"; + public static final String PACKAGE_VERIFIER_STATE = "package_verifier_state"; /** - * Specifies whether the current app context on scren (assist data) will be sent to the - * assist application (active voice interaction service). - * + * Specifies additional package name for broadcasting the CMAS messages. * @hide */ - public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled"; + public static final String CMAS_ADDITIONAL_BROADCAST_PKG = "cmas_additional_broadcast_pkg"; /** - * Specifies whether a screenshot of the screen contents will be sent to the assist - * application (active voice interaction service). - * + * Whether the launcher should show any notification badges. + * The value is boolean (1 or 0). * @hide */ - public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled"; + public static final String NOTIFICATION_BADGING = "notification_badging"; + + private static final Validator NOTIFICATION_BADGING_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Specifies whether the screen will show an animation if screen contents are sent to the - * assist application (active voice interaction service). - * - * Note that the disclosure will be forced for third-party assistants or if the device - * does not support disabling it. - * + * Comma separated list of QS tiles that have been auto-added already. * @hide */ - public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled"; + public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles"; + + private static final Validator QS_AUTO_ADDED_TILES_VALIDATOR = new Validator() { + @Override + public boolean validate(@Nullable String value) { + if (value == null) { + return false; + } + String[] tiles = value.split(","); + boolean valid = true; + for (String tile : tiles) { + // tile can be any non-empty string as specified by OEM + valid |= ((tile.length() > 0) && ANY_STRING_VALIDATOR.validate(tile)); + } + return valid; + } + }; /** - * Control if rotation suggestions are sent to System UI when in rotation locked mode. - * Done to enable screen rotation while the the screen rotation is locked. Enabling will - * poll the accelerometer in rotation locked mode. - * - * If 0, then rotation suggestions are not sent to System UI. If 1, suggestions are sent. - * + * Whether the Lockdown button should be shown in the power menu. * @hide */ + public static final String LOCKDOWN_IN_POWER_MENU = "lockdown_in_power_menu"; - public static final String SHOW_ROTATION_SUGGESTIONS = "show_rotation_suggestions"; + private static final Validator LOCKDOWN_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR; /** - * The disabled state of SHOW_ROTATION_SUGGESTIONS. + * Backup manager behavioral parameters. + * This is encoded as a key=value list, separated by commas. Ex: + * + * "key_value_backup_interval_milliseconds=14400000,key_value_backup_require_charging=true" + * + * The following keys are supported: + * + *

+         * key_value_backup_interval_milliseconds  (long)
+         * key_value_backup_fuzz_milliseconds      (long)
+         * key_value_backup_require_charging       (boolean)
+         * key_value_backup_required_network_type  (int)
+         * full_backup_interval_milliseconds       (long)
+         * full_backup_require_charging            (boolean)
+         * full_backup_required_network_type       (int)
+         * backup_finished_notification_receivers  (String[])
+         * 
+ * + * backup_finished_notification_receivers uses ":" as delimeter for values. + * + *

+ * Type: string * @hide */ - public static final int SHOW_ROTATION_SUGGESTIONS_DISABLED = 0x0; + public static final String BACKUP_MANAGER_CONSTANTS = "backup_manager_constants"; - /** - * The enabled state of SHOW_ROTATION_SUGGESTIONS. - * @hide - */ - public static final int SHOW_ROTATION_SUGGESTIONS_ENABLED = 0x1; /** - * The default state of SHOW_ROTATION_SUGGESTIONS. + * Local transport parameters so we can configure it for tests. + * This is encoded as a key=value list, separated by commas. + * + * The following keys are supported: + * + *

+         * fake_encryption_flag  (boolean)
+         * 
+ * + *

+ * Type: string * @hide */ - public static final int SHOW_ROTATION_SUGGESTIONS_DEFAULT = - SHOW_ROTATION_SUGGESTIONS_ENABLED; + public static final String BACKUP_LOCAL_TRANSPORT_PARAMETERS = + "backup_local_transport_parameters"; /** - * The number of accepted rotation suggestions. Used to determine if the user has been - * introduced to rotation suggestions. + * Flag to set if the system should predictively attempt to re-enable Bluetooth while + * the user is driving. * @hide */ - public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED = - "num_rotation_suggestions_accepted"; + public static final String BLUETOOTH_ON_WHILE_DRIVING = "bluetooth_on_while_driving"; /** - * Read only list of the service components that the current user has explicitly allowed to - * see and assist with all of the user's notifications. + * What behavior should be invoked when the volume hush gesture is triggered + * One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE, VOLUME_HUSH_MUTE_NO_MEDIA. * - * @deprecated Use - * {@link NotificationManager#isNotificationListenerAccessGranted(ComponentName)}. * @hide */ - @Deprecated - public static final String ENABLED_NOTIFICATION_ASSISTANT = - "enabled_notification_assistant"; + public static final String VOLUME_HUSH_GESTURE = "volume_hush_gesture"; - private static final Validator ENABLED_NOTIFICATION_ASSISTANT_VALIDATOR = - new SettingsValidators.ComponentNameListValidator(":"); + /** @hide */ public static final int VOLUME_HUSH_OFF = 0; + /** @hide */ public static final int VOLUME_HUSH_VIBRATE = 1; + /** @hide */ public static final int VOLUME_HUSH_MUTE = 2; + /** @hide */ public static final int VOLUME_HUSH_MUTE_NO_MEDIA = 3; + + private static final Validator VOLUME_HUSH_GESTURE_VALIDATOR = + NON_NEGATIVE_INTEGER_VALIDATOR; /** - * Read only list of the service components that the current user has explicitly allowed to - * see all of the user's notifications, separated by ':'. - * + * The number of times (integer) the user has manually enabled battery saver. * @hide - * @deprecated Use - * {@link NotificationManager#isNotificationAssistantAccessGranted(ComponentName)}. */ - @Deprecated - public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners"; - - private static final Validator ENABLED_NOTIFICATION_LISTENERS_VALIDATOR = - new SettingsValidators.ComponentNameListValidator(":"); + public static final String LOW_POWER_MANUAL_ACTIVATION_COUNT = + "low_power_manual_activation_count"; /** - * Read only list of the packages that the current user has explicitly allowed to - * manage do not disturb, separated by ':'. + * Whether the "first time battery saver warning" dialog needs to be shown (0: default) + * or not (1). * - * @deprecated Use {@link NotificationManager#isNotificationPolicyAccessGranted()}. * @hide */ - @Deprecated - @TestApi - public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = - "enabled_notification_policy_access_packages"; - - private static final Validator ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR = - new SettingsValidators.PackageNameListValidator(":"); + public static final String LOW_POWER_WARNING_ACKNOWLEDGED = + "low_power_warning_acknowledged"; /** - * Defines whether managed profile ringtones should be synced from it's parent profile - *

- * 0 = ringtones are not synced - * 1 = ringtones are synced from the profile's parent (default) - *

- * This value is only used for managed profiles. + * 0 (default) Auto battery saver suggestion has not been suppressed. 1) it has been + * suppressed. * @hide */ - @TestApi - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) - public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds"; - - private static final Validator SYNC_PARENT_SOUNDS_VALIDATOR = BOOLEAN_VALIDATOR; - - /** @hide */ - public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations"; + public static final String SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION = + "suppress_auto_battery_saver_suggestion"; /** - * This is the query URI for finding a print service to install. - * + * List of packages, which data need to be unconditionally cleared before full restore. + * Type: string * @hide */ - public static final String PRINT_SERVICE_SEARCH_URI = "print_service_search_uri"; + public static final String PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE = + "packages_to_clear_data_before_full_restore"; /** - * This is the query URI for finding a NFC payment service to install. + * Select various actions for squeeze gesture * * @hide */ - public static final String PAYMENT_SERVICE_SEARCH_URI = "payment_service_search_uri"; + public static final String SQUEEZE_SELECTION_SMART_ACTIONS = "squeeze_selection_smart_actions"; /** - * This is the query URI for finding a auto fill service to install. + * Select various actions for long squeeze gesture * * @hide */ - public static final String AUTOFILL_SERVICE_SEARCH_URI = "autofill_service_search_uri"; - - /** - * If enabled, apps should try to skip any introductory hints on first launch. This might - * apply to users that are already familiar with the environment or temporary users. - *

- * Type : int (0 to show hints, 1 to skip showing hints) - */ - public static final String SKIP_FIRST_USE_HINTS = "skip_first_use_hints"; + public static final String LONG_SQUEEZE_SELECTION_SMART_ACTIONS = "long_squeeze_selection_smart_actions"; /** - * Persisted playback time after a user confirmation of an unsafe volume level. - * * @hide */ - public static final String UNSAFE_VOLUME_MUSIC_ACTIVE_MS = "unsafe_volume_music_active_ms"; - - /** - * This preference enables notification display on the lockscreen. + public static final String PRIVACY_GUARD_DEFAULT = "privacy_guard_default"; + /** * @hide */ - public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = - "lock_screen_show_notifications"; + public static final String PRIVACY_GUARD_NOTIFICATION = "privacy_guard_notification"; /** - * List of TV inputs that are currently hidden. This is a string - * containing the IDs of all hidden TV inputs. Each ID is encoded by - * {@link android.net.Uri#encode(String)} and separated by ':'. + * Display style of the status bar battery information + * 0: Display the battery an icon in portrait mode + * 1: Display the battery as a circle + * 2: Display the battery as a dotted circle + * 3: Display the battery as text + * 4: Do not display the battery + * default: 0 * @hide */ - public static final String TV_INPUT_HIDDEN_INPUTS = "tv_input_hidden_inputs"; + public static final String STATUS_BAR_BATTERY_STYLE = "status_bar_battery_style"; + + /** @hide */ + public static final Validator STATUS_BAR_BATTERY_STYLE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 4); /** - * List of custom TV input labels. This is a string containing - * pairs. TV input id and custom name are encoded by {@link android.net.Uri#encode(String)} - * and separated by ','. Each pair is separated by ':'. + * The TCP/IP port to run ADB on, or -1 for USB * @hide */ - public static final String TV_INPUT_CUSTOM_LABELS = "tv_input_custom_labels"; + public static final String ADB_PORT = "adb_port"; /** - * Whether automatic routing of system audio to USB audio peripheral is disabled. - * The value is boolean (1 or 0), where 1 means automatic routing is disabled, - * and 0 means automatic routing is enabled. + * Lockscreen Visualizer * * @hide */ - public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED = - "usb_audio_automatic_routing_disabled"; + public static final String LOCKSCREEN_VISUALIZER_ENABLED = "lockscreen_visualizer"; + /** @hide */ + private static final Validator LOCKSCREEN_VISUALIZER_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * The timeout in milliseconds before the device fully goes to sleep after - * a period of inactivity. This value sets an upper bound on how long the device - * will stay awake or dreaming without user activity. It should generally - * be longer than {@link Settings.System#SCREEN_OFF_TIMEOUT} as otherwise the device - * will sleep before it ever has a chance to dream. - *

- * Use -1 to disable this timeout. - *

+ * Ambient Display Visualizer * * @hide */ - public static final String SLEEP_TIMEOUT = "sleep_timeout"; + public static final String AMBIENT_VISUALIZER_ENABLED = "ambient_visualizer"; + /** @hide */ + private static final Validator AMBIENT_VISUALIZER_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; - private static final Validator SLEEP_TIMEOUT_VALIDATOR = - new SettingsValidators.InclusiveIntegerRangeValidator(-1, Integer.MAX_VALUE); + /** Whether to vibrate when quick settings tile is pressed. + * + * @hide + */ + public static final String QUICK_SETTINGS_TILES_VIBRATE = "quick_settings_vibrate"; + /** @hide */ + private static final Validator QUICK_SETTINGS_TILES_VIBRATE_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * Controls whether double tap to wake is enabled. * @hide */ - public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake"; - - private static final Validator DOUBLE_TAP_TO_WAKE_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String NAVIGATION_BAR_HEIGHT_LANDSCAPE = "navigation_bar_height_landscape"; /** - * The current assistant component. It could be a voice interaction service, - * or an activity that handles ACTION_ASSIST, or empty which means using the default - * handling. - * * @hide */ - public static final String ASSISTANT = "assistant"; + public static final String NAVIGATION_BAR_HEIGHT = "navigation_bar_height"; /** - * Whether the camera launch gesture should be disabled. - * * @hide */ - public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled"; - - private static final Validator CAMERA_GESTURE_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String NAVIGATION_BAR_WIDTH = "navigation_bar_width"; /** - * Whether the camera launch gesture to double tap the power button when the screen is off - * should be disabled. - * + * Add or remove software navigation bar * @hide */ - public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED = - "camera_double_tap_power_gesture_disabled"; - - private static final Validator CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR = + public static final String NAVIGATION_BAR_VISIBLE = "navigation_bar_visible"; + /** @hide */ + private static final Validator NAVIGATION_BAR_VISIBLE_VALIDATOR = BOOLEAN_VALIDATOR; /** - * Whether the camera double twist gesture to flip between front and back mode should be - * enabled. + * Navigation bar mode * * @hide */ - public static final String CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED = - "camera_double_twist_to_flip_enabled"; - - private static final Validator CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + public static final String NAVIGATION_BAR_MODE = "navigation_bar_mode"; /** - * Whether the swipe up gesture to switch apps should be enabled. + * Fling actions * * @hide */ - public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED = - "swipe_up_to_switch_apps_enabled"; - - private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + public static final String FLING_GESTURE_ACTIONS = "fling_gesture_configs"; /** - * Whether or not the smart camera lift trigger that launches the camera when the user moves - * the phone into a position for taking photos should be enabled. + * Fling logo visible * * @hide */ - public static final String CAMERA_LIFT_TRIGGER_ENABLED = "camera_lift_trigger_enabled"; + public static final String FLING_LOGO_VISIBLE = "fling_logo_visible"; /** - * The default enable state of the camera lift trigger. + * Fling logo animates * * @hide */ - public static final int CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT = 1; + public static final String FLING_LOGO_ANIMATES= "fling_logo_animates"; /** - * Whether the assist gesture should be enabled. + * Fling logo animates * * @hide */ - public static final String ASSIST_GESTURE_ENABLED = "assist_gesture_enabled"; - - private static final Validator ASSIST_GESTURE_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + //public static final String FLING_LOGO_COLOR = "fling_logo_color"; /** - * Sensitivity control for the assist gesture. + * Fling logo opacity * * @hide */ - public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity"; + public static final String FLING_LOGO_OPACITY = "fling_logo_opacity"; /** - * Whether the assist gesture should silence alerts. + * Fling pulse music visualizer * * @hide */ - public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED = - "assist_gesture_silence_alerts_enabled"; - - private static final Validator ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + public static final String FLING_PULSE_ENABLED = "fling_pulse_enabled"; /** - * Whether the assist gesture should wake the phone. + * Fling pulse music visualizer color * * @hide */ - public static final String ASSIST_GESTURE_WAKE_ENABLED = - "assist_gesture_wake_enabled"; - - private static final Validator ASSIST_GESTURE_WAKE_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; + public static final String FLING_PULSE_COLOR = "fling_pulse_color"; /** - * Whether Assist Gesture Deferred Setup has been completed + * Fling ripple effect * * @hide */ - public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete"; + public static final String FLING_RIPPLE_ENABLED = "fling_ripple_enabled"; /** - * Control whether Night display is currently activated. + * Fling ripple color + * * @hide */ - public static final String NIGHT_DISPLAY_ACTIVATED = "night_display_activated"; + public static final String FLING_RIPPLE_COLOR = "fling_ripple_color"; /** - * Control whether Night display will automatically activate/deactivate. + * Fling gesture trails on/off + * * @hide */ - public static final String NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode"; - - private static final Validator NIGHT_DISPLAY_AUTO_MODE_VALIDATOR = - new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); + public static final String FLING_TRAILS_ENABLED = "fling_trails_enabled"; /** - * Control the color temperature of Night Display, represented in Kelvin. + * Fling gesture trails color + * * @hide */ - public static final String NIGHT_DISPLAY_COLOR_TEMPERATURE = - "night_display_color_temperature"; - - private static final Validator NIGHT_DISPLAY_COLOR_TEMPERATURE_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + public static final String FLING_TRAILS_COLOR = "fling_trails_color"; /** - * Custom time when Night display is scheduled to activate. - * Represented as milliseconds from midnight (e.g. 79200000 == 10pm). + * Pulse accent color + * * @hide */ - public static final String NIGHT_DISPLAY_CUSTOM_START_TIME = - "night_display_custom_start_time"; - - private static final Validator NIGHT_DISPLAY_CUSTOM_START_TIME_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + public static final String PULSE_ACCENT_COLOR_ENABLED = "pulse_accent_color_enabled"; /** - * Custom time when Night display is scheduled to deactivate. - * Represented as milliseconds from midnight (e.g. 21600000 == 6am). + * Fling pulse bars smoothing + * * @hide */ - public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time"; - - private static final Validator NIGHT_DISPLAY_CUSTOM_END_TIME_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + public static final String FLING_PULSE_SMOOTHING_ENABLED = "fling_pulse_smoothing_enabled"; /** - * A String representing the LocalDateTime when Night display was last activated. Use to - * decide whether to apply the current activated state after a reboot or user change. In - * legacy cases, this is represented by the time in milliseconds (since epoch). + * Fling pulse lavalamp psychedelic colors + * * @hide */ - public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME = - "night_display_last_activated_time"; + public static final String FLING_PULSE_LAVALAMP_ENABLED = "fling_pulse_lavalamp_enabled"; /** - * Names of the service components that the current user has explicitly allowed to - * be a VR mode listener, separated by ':'. + * Fling pulse lavalamp animation speed * * @hide */ - public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners"; - - private static final Validator ENABLED_VR_LISTENERS_VALIDATOR = - new SettingsValidators.ComponentNameListValidator(":"); + public static final String FLING_PULSE_LAVALAMP_SPEED = "fling_pulse_lavalamp_speed"; /** - * Behavior of the display while in VR mode. - * - * One of {@link #VR_DISPLAY_MODE_LOW_PERSISTENCE} or {@link #VR_DISPLAY_MODE_OFF}. + * Fling pulse lavalamp start and end colors * * @hide */ - public static final String VR_DISPLAY_MODE = "vr_display_mode"; - - private static final Validator VR_DISPLAY_MODE_VALIDATOR = - new SettingsValidators.DiscreteValueValidator(new String[]{"0", "1"}); + public static final String FLING_PULSE_LAVALAMP_COLOR_FROM = "fling_lavalamp_color_from"; /** - * Lower the display persistence while the system is in VR mode. - * - * @see PackageManager#FEATURE_VR_MODE_HIGH_PERFORMANCE + * Fling pulse lavalamp start and end colors * - * @hide. + * @hide */ - public static final int VR_DISPLAY_MODE_LOW_PERSISTENCE = 0; + public static final String FLING_PULSE_LAVALAMP_COLOR_TO = "fling_lavalamp_color_to"; /** - * Do not alter the display persistence while the system is in VR mode. - * - * @see PackageManager#FEATURE_VR_MODE_HIGH_PERFORMANCE + * Pulse renderer implementation * - * @hide. + * @hide */ - public static final int VR_DISPLAY_MODE_OFF = 1; + public static final String PULSE_RENDER_STYLE_URI = "pulse_render_style"; /** - * Whether CarrierAppUtils#disableCarrierAppsUntilPrivileged has been executed at least - * once. - * - *

This is used to ensure that we only take one pass which will disable apps that are not - * privileged (if any). From then on, we only want to enable apps (when a matching SIM is - * inserted), to avoid disabling an app that the user might actively be using. - * - *

Will be set to 1 once executed. + * time it takes to execute Fling long press action * * @hide */ - public static final String CARRIER_APPS_HANDLED = "carrier_apps_handled"; + public static final String FLING_LONGPRESS_TIMEOUT = "fling_longpress_timeout"; /** - * Whether parent user can access remote contact in managed profile. + * distance to swipe right when device is in portrait orientation to + * trigger action * * @hide */ - public static final String MANAGED_PROFILE_CONTACT_REMOTE_SEARCH = - "managed_profile_contact_remote_search"; + public static final String FLING_LONGSWIPE_THRESHOLD_RIGHT_PORT = "fling_longswipe_threshold_right_port"; /** - * Whether or not the automatic storage manager is enabled and should run on the device. + * distance to swipe left when device is in portrait orientation to + * trigger action * * @hide */ - public static final String AUTOMATIC_STORAGE_MANAGER_ENABLED = - "automatic_storage_manager_enabled"; + public static final String FLING_LONGSWIPE_THRESHOLD_LEFT_PORT = "fling_longswipe_threshold_left_port"; /** - * How many days of information for the automatic storage manager to retain on the device. + * distance to swipe right when device is in landscape orientation to + * trigger action. Apples to a horizontal layout (tablet/phablet) * * @hide */ - public static final String AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN = - "automatic_storage_manager_days_to_retain"; - - private static final Validator AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + public static final String FLING_LONGSWIPE_THRESHOLD_RIGHT_LAND = "fling_longswipe_threshold_right_land"; /** - * Default number of days of information for the automatic storage manager to retain. + * distance to swipe left when device is in landscape orientation to + * trigger action. Apples to a horizontal layout (tablet/phablet) * * @hide */ - public static final int AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_DEFAULT = 90; + public static final String FLING_LONGSWIPE_THRESHOLD_LEFT_LAND = "fling_longswipe_threshold_left_land"; /** - * How many bytes the automatic storage manager has cleared out. + * distance to swipe up when device is in landscape orientation to + * trigger action. Apples to a vertical layout (phones) * * @hide */ - public static final String AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED = - "automatic_storage_manager_bytes_cleared"; - + public static final String FLING_LONGSWIPE_THRESHOLD_UP_LAND = "fling_longswipe_threshold_up_land"; /** - * Last run time for the automatic storage manager. + * distance to swipe down when device is in landscape orientation to + * trigger action. Apples to a horizontal layout (phones) * * @hide */ - public static final String AUTOMATIC_STORAGE_MANAGER_LAST_RUN = - "automatic_storage_manager_last_run"; + public static final String FLING_LONGSWIPE_THRESHOLD_DOWN_LAND = "fling_longswipe_threshold_down_land"; /** - * If the automatic storage manager has been disabled by policy. Note that this doesn't - * mean that the automatic storage manager is prevented from being re-enabled -- this only - * means that it was turned off by policy at least once. + * width of Fling trails stroke, in density pixels * * @hide */ - public static final String AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY = - "automatic_storage_manager_turned_off_by_policy"; + public static final String FLING_TRAILS_WIDTH = "fling_trails_width"; /** - * Whether SystemUI navigation keys is enabled. + * Navbar buttons transparency * @hide */ - public static final String SYSTEM_NAVIGATION_KEYS_ENABLED = - "system_navigation_keys_enabled"; - - private static final Validator SYSTEM_NAVIGATION_KEYS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String NAVBAR_BUTTONS_ALPHA = "navbar_buttons_alpha"; /** - * Holds comma separated list of ordering of QS tiles. + * Custom Pulse Widths * @hide */ - public static final String QS_TILES = "sysui_qs_tiles"; - - private static final Validator QS_TILES_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - if (value == null) { - return false; - } - String[] tiles = value.split(","); - boolean valid = true; - for (String tile : tiles) { - // tile can be any non-empty string as specified by OEM - valid |= ((tile.length() > 0) && ANY_STRING_VALIDATOR.validate(tile)); - } - return valid; - } - }; + public static final String PULSE_CUSTOM_DIMEN = "pulse_custom_dimen"; /** - * Specifies whether the web action API is enabled. - * + * Custom Spacing Between Pulse Bars * @hide */ - @SystemApi - public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled"; + public static final String PULSE_CUSTOM_DIV = "pulse_custom_div"; /** - * Has this pairable device been paired or upgraded from a previously paired system. + * Custom Pulse Block Size * @hide */ - public static final String DEVICE_PAIRED = "device_paired"; + public static final String PULSE_FILLED_BLOCK_SIZE = "pulse_filled_block_size"; /** - * Integer state indicating whether package verifier is enabled. - * TODO(b/34259924): Remove this setting. - * + * Custom Spacing Between Pulse Blocks * @hide */ - public static final String PACKAGE_VERIFIER_STATE = "package_verifier_state"; + public static final String PULSE_EMPTY_BLOCK_SIZE = "pulse_empty_block_size"; /** - * Specifies additional package name for broadcasting the CMAS messages. + * Custom Pulse Sanity Levels * @hide */ - public static final String CMAS_ADDITIONAL_BROADCAST_PKG = "cmas_additional_broadcast_pkg"; + public static final String PULSE_CUSTOM_FUDGE_FACTOR = "pulse_custom_fudge_factor"; /** - * Whether the launcher should show any notification badges. - * The value is boolean (1 or 0). + * Pulse Fudge Factor * @hide */ - public static final String NOTIFICATION_BADGING = "notification_badging"; - - private static final Validator NOTIFICATION_BADGING_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String PULSE_SOLID_FUDGE_FACTOR = "pulse_solid_fudge_factor"; /** - * Comma separated list of QS tiles that have been auto-added already. + * Pulse Lavamp Animation Speed * @hide */ - public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles"; - - private static final Validator QS_AUTO_ADDED_TILES_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - if (value == null) { - return false; - } - String[] tiles = value.split(","); - boolean valid = true; - for (String tile : tiles) { - // tile can be any non-empty string as specified by OEM - valid |= ((tile.length() > 0) && ANY_STRING_VALIDATOR.validate(tile)); - } - return valid; - } - }; + public static final String PULSE_LAVALAMP_SOLID_SPEED = "lava_lamp_solid_speed"; /** - * Whether the Lockdown button should be shown in the power menu. + * Pulse Solid units count * @hide */ - public static final String LOCKDOWN_IN_POWER_MENU = "lockdown_in_power_menu"; - - private static final Validator LOCKDOWN_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR; + public static final String PULSE_SOLID_UNITS_COUNT = "pulse_solid_units_count"; /** - * Backup manager behavioral parameters. - * This is encoded as a key=value list, separated by commas. Ex: - * - * "key_value_backup_interval_milliseconds=14400000,key_value_backup_require_charging=true" - * - * The following keys are supported: - * - *

-         * key_value_backup_interval_milliseconds  (long)
-         * key_value_backup_fuzz_milliseconds      (long)
-         * key_value_backup_require_charging       (boolean)
-         * key_value_backup_required_network_type  (int)
-         * full_backup_interval_milliseconds       (long)
-         * full_backup_require_charging            (boolean)
-         * full_backup_required_network_type       (int)
-         * backup_finished_notification_receivers  (String[])
-         * 
- * - * backup_finished_notification_receivers uses ":" as delimeter for values. - * - *

- * Type: string + * Pulse Solid units opacity * @hide */ - public static final String BACKUP_MANAGER_CONSTANTS = "backup_manager_constants"; - + public static final String PULSE_SOLID_UNITS_OPACITY = "pulse_solid_units_opacity"; /** - * Local transport parameters so we can configure it for tests. - * This is encoded as a key=value list, separated by commas. - * - * The following keys are supported: - * - *

-         * fake_encryption_flag  (boolean)
-         * 
- * - *

- * Type: string + * SmartBar buttons opacity on Pulse * @hide */ - public static final String BACKUP_LOCAL_TRANSPORT_PARAMETERS = - "backup_local_transport_parameters"; + public static final String PULSE_CUSTOM_BUTTONS_OPACITY = "pulse_custom_buttons_opacity"; /** - * Flag to set if the system should predictively attempt to re-enable Bluetooth while - * the user is driving. + * Long press delay for smartbar buttons * @hide + * 0: Default (fast) + * 1: Normal delay + * 2: Long delay */ - public static final String BLUETOOTH_ON_WHILE_DRIVING = "bluetooth_on_while_driving"; + public static final String SMARTBAR_LONGPRESS_DELAY = "smartbar_longpress_delay"; /** - * What behavior should be invoked when the volume hush gesture is triggered - * One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE. - * + * Scaling value for smartbar custom button icon * @hide */ - public static final String VOLUME_HUSH_GESTURE = "volume_hush_gesture"; - - /** @hide */ public static final int VOLUME_HUSH_OFF = 0; - /** @hide */ public static final int VOLUME_HUSH_VIBRATE = 1; - /** @hide */ public static final int VOLUME_HUSH_MUTE = 2; + public static final String SMARTBAR_CUSTOM_ICON_SIZE = "smartbar_custom_icon_size"; - private static final Validator VOLUME_HUSH_GESTURE_VALIDATOR = - NON_NEGATIVE_INTEGER_VALIDATOR; + /** + * Whether to switch Fling double tap right/left actions to kb cursors when a keyboard is showing + * @hide + */ + public static final String FLING_KEYBOARD_CURSORS = "fling_keyboard_cursors"; /** - * The number of times (integer) the user has manually enabled battery saver. + * Whether to use automatic color for Pulse * @hide */ - public static final String LOW_POWER_MANUAL_ACTIVATION_COUNT = - "low_power_manual_activation_count"; + public static final String PULSE_AUTO_COLOR = "pulse_auto_color"; /** - * Whether the "first time battery saver warning" dialog needs to be shown (0: default) - * or not (1). - * + * Whether to enable double tap to sleep for smartbar * @hide */ - public static final String LOW_POWER_WARNING_ACKNOWLEDGED = - "low_power_warning_acknowledged"; + public static final String SMARTBAR_DOUBLETAP_SLEEP = "smartbar_doubletap_sleep"; /** - * 0 (default) Auto battery saver suggestion has not been suppressed. 1) it has been - * suppressed. + * Boolean value whether to link ringtone and notification volume * @hide */ - public static final String SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION = - "suppress_auto_battery_saver_suggestion"; + public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification"; + /** @hide */ + private static final Validator VOLUME_LINK_NOTIFICATION_VALIDATOR = + BOOLEAN_VALIDATOR; /** - * List of packages, which data need to be unconditionally cleared before full restore. - * Type: string + * Whether tethering is allowed to use VPN upstreams + * 0 = false, 1 = true * @hide */ - public static final String PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE = - "packages_to_clear_data_before_full_restore"; + public static final String TETHERING_ALLOW_VPN_UPSTREAMS = "tethering_allow_vpn_upstreams"; + + /** @hide */ + public static final Validator TETHERING_ALLOW_VPN_UPSTREAMS_VALIDATOR = BOOLEAN_VALIDATOR; /** * This are the settings to be backed up. @@ -8007,6 +9988,7 @@ public boolean validate(@Nullable String value) { CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, SWIPE_UP_TO_SWITCH_APPS_ENABLED, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, + TORCH_POWER_BUTTON_GESTURE, SYSTEM_NAVIGATION_KEYS_ENABLED, QS_TILES, DOZE_ENABLED, @@ -8026,9 +10008,16 @@ public boolean validate(@Nullable String value) { SCREENSAVER_ACTIVATE_ON_SLEEP, LOCKDOWN_IN_POWER_MENU, SHOW_FIRST_CRASH_DIALOG_DEV_OPTION, + VOLUME_LINK_NOTIFICATION, VOLUME_HUSH_GESTURE, MANUAL_RINGER_TOGGLE_COUNT, HUSH_GESTURE_USED, + STATUS_BAR_BATTERY_STYLE, + AMBIENT_VISUALIZER_ENABLED, + LOCKSCREEN_VISUALIZER_ENABLED, + QUICK_SETTINGS_TILES_VIBRATE, + LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, + LOCK_SCREEN_SHOW_NOTIFICATIONS, }; /** @@ -8143,8 +10132,12 @@ public boolean validate(@Nullable String value) { SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR); + VALIDATORS.put(TORCH_POWER_BUTTON_GESTURE, + TORCH_POWER_BUTTON_GESTURE_VALIDATOR); VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED, SYSTEM_NAVIGATION_KEYS_ENABLED_VALIDATOR); + VALIDATORS.put(FP_SWIPE_TO_DISMISS_NOTIFICATIONS, + FP_SWIPE_TO_DISMISS_NOTIFICATIONS_VALIDATOR); VALIDATORS.put(QS_TILES, QS_TILES_VALIDATOR); VALIDATORS.put(DOZE_ENABLED, DOZE_ENABLED_VALIDATOR); VALIDATORS.put(DOZE_PULSE_ON_PICK_UP, DOZE_PULSE_ON_PICK_UP_VALIDATOR); @@ -8175,8 +10168,15 @@ public boolean validate(@Nullable String value) { ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR); //legacy restore setting VALIDATORS.put(HUSH_GESTURE_USED, HUSH_GESTURE_USED_VALIDATOR); VALIDATORS.put(MANUAL_RINGER_TOGGLE_COUNT, MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR); + VALIDATORS.put(VOLUME_LINK_NOTIFICATION, VOLUME_LINK_NOTIFICATION_VALIDATOR); + VALIDATORS.put(STATUS_BAR_BATTERY_STYLE, STATUS_BAR_BATTERY_STYLE_VALIDATOR); + VALIDATORS.put(LOCK_POWER_MENU_DISABLED, LOCK_POWER_MENU_DISABLED_VALIDATOR); VALIDATORS.put(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR); VALIDATORS.put(LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR); + VALIDATORS.put(NAVIGATION_BAR_VISIBLE, NAVIGATION_BAR_VISIBLE_VALIDATOR); + VALIDATORS.put(LOCKSCREEN_VISUALIZER_ENABLED, LOCKSCREEN_VISUALIZER_ENABLED_VALIDATOR); + VALIDATORS.put(AMBIENT_VISUALIZER_ENABLED, AMBIENT_VISUALIZER_ENABLED_VALIDATOR); + VALIDATORS.put(QUICK_SETTINGS_TILES_VIBRATE, QUICK_SETTINGS_TILES_VIBRATE_VALIDATOR); } /** @@ -11072,6 +13072,30 @@ public boolean validate(@Nullable String value) { */ public static final String KEEP_PROFILE_IN_BACKGROUND = "keep_profile_in_background"; + /** + * Whether or not to use aggressive device idle constants and ignore motion. + * Type: int (0 for false, 1 for true) + * Default: 0 + * @hide + */ + public static final String AGGRESSIVE_IDLE_ENABLED = "aggressive_idle_enabled"; + + /** + * Whether or not to use aggressive app idle constants. + * Type: int (0 for false, 1 for true) + * Default: 0 + * @hide + */ + public static final String AGGRESSIVE_STANDBY_ENABLED = "aggressive_standby_enabled"; + + /** + * Flag to automatically enable Aggressive Idle and Standby with battery saver. + * Type: int (0 for false, 1 for true) + * Default: 0 + * @hide + */ + public static final String AGGRESSIVE_BATTERY_SAVER = "aggressive_battery_saver"; + /** * Get the key that retrieves a bluetooth headset's priority. * @hide @@ -11941,6 +13965,18 @@ public boolean validate(@Nullable String value) { public static final String LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED = "location_settings_link_to_permissions_enabled"; + /** + * Defines the screen-off animation to display + * @hide + */ + public static final String SCREEN_OFF_ANIMATION = "screen_off_animation"; + + /** + * Whether to show a screen-on animation + * @hide + */ + public static final String SCREEN_ON_ANIMATION = "screen_on_animation"; + /** * Flag to set the waiting time for euicc factory reset inside System > Settings * Type: long @@ -12064,6 +14100,10 @@ public boolean validate(@Nullable String value) { */ public static final String MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY = "max_sound_trigger_detection_service_ops_per_day"; + /** + * @hide + */ + public static final String SHOW_CPU_OVERLAY = "show_cpu_overlay"; /** * Settings to backup. This is here so that it's in the same place as the settings diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java index 09bba4b459f6..3ee4dbac9828 100644 --- a/core/java/android/service/carrier/CarrierIdentifier.java +++ b/core/java/android/service/carrier/CarrierIdentifier.java @@ -49,6 +49,7 @@ public CarrierIdentifier[] newArray(int i) { private @Nullable String mImsi; private @Nullable String mGid1; private @Nullable String mGid2; + private @Nullable String mIccid; public CarrierIdentifier(String mcc, String mnc, @Nullable String spn, @Nullable String imsi, @Nullable String gid1, @Nullable String gid2) { @@ -58,6 +59,14 @@ public CarrierIdentifier(String mcc, String mnc, @Nullable String spn, @Nullable mImsi = imsi; mGid1 = gid1; mGid2 = gid2; + mIccid = null; + } + + /** @hide */ + public CarrierIdentifier(String mcc, String mnc, @Nullable String spn, @Nullable String imsi, + @Nullable String gid1, @Nullable String gid2I, @Nullable String iccid) { + this(mcc, mnc, spn, imsi, gid1, gid2I); + mIccid = iccid; } /** @@ -84,6 +93,7 @@ public CarrierIdentifier(byte[] mccMnc, @Nullable String gid1, @Nullable String mGid2 = gid2; mSpn = null; mImsi = null; + mIccid = null; } /** @hide */ @@ -125,6 +135,13 @@ public String getGid2() { return mGid2; } + /** Get the ICCID. + * @hide */ + @Nullable + public String getIccid() { + return mIccid; + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -140,7 +157,8 @@ public boolean equals(Object obj) { && Objects.equals(mSpn, that.mSpn) && Objects.equals(mImsi, that.mImsi) && Objects.equals(mGid1, that.mGid1) - && Objects.equals(mGid2, that.mGid2); + && Objects.equals(mGid2, that.mGid2) + && Objects.equals(mIccid, that.mIccid); } @Override @@ -152,6 +170,7 @@ public int hashCode() { result = 31 * result + Objects.hashCode(mImsi); result = 31 * result + Objects.hashCode(mGid1); result = 31 * result + Objects.hashCode(mGid2); + result = 31 * result + Objects.hashCode(mIccid); return result; } @@ -168,6 +187,7 @@ public void writeToParcel(Parcel out, int flags) { out.writeString(mImsi); out.writeString(mGid1); out.writeString(mGid2); + out.writeString(mIccid); } @Override @@ -179,6 +199,7 @@ public String toString() { + ",imsi=" + mImsi + ",gid1=" + mGid1 + ",gid2=" + mGid2 + + ",iccid=" + mIccid + "}"; } @@ -190,6 +211,7 @@ public void readFromParcel(Parcel in) { mImsi = in.readString(); mGid1 = in.readString(); mGid2 = in.readString(); + mIccid = in.readString(); } /** @hide */ @@ -199,5 +221,6 @@ public interface MatchType { int IMSI_PREFIX = 2; int GID1 = 3; int GID2 = 4; + int ICCID = 5; } } diff --git a/core/java/android/service/gesture/IGestureService.aidl b/core/java/android/service/gesture/IGestureService.aidl new file mode 100644 index 000000000000..1944d5075d2e --- /dev/null +++ b/core/java/android/service/gesture/IGestureService.aidl @@ -0,0 +1,11 @@ +package android.service.gesture; + +import android.app.PendingIntent; + +/** @hide */ +interface IGestureService { + + void setOnLongPressPendingIntent(in PendingIntent pendingIntent); + void setOnDoubleClickPendingIntent(in PendingIntent pendingIntent); + +} diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 5edf7ce47658..0cb879d1579d 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -371,7 +371,7 @@ private static boolean sameCondition(ZenRule rule) { } private static int[] generateMinuteBuckets() { - final int maxHrs = 12; + final int maxHrs = 24; final int[] buckets = new int[maxHrs + 3]; buckets[0] = 15; buckets[1] = 30; diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 7f75f0a68660..b7513907682f 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -1361,7 +1361,7 @@ public void executeMessage(Message message) { return; } case MSG_UPDATE_SURFACE: - mEngine.updateSurface(true, false, false); + mEngine.updateSurface(true, false, true/*false*/); break; case MSG_VISIBILITY_CHANGED: if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java index 88e2edeee552..3eb24e499a9d 100644 --- a/core/java/android/speech/SpeechRecognizer.java +++ b/core/java/android/speech/SpeechRecognizer.java @@ -260,6 +260,7 @@ public void setRecognitionListener(RecognitionListener listener) { * not set explicitly, default values will be used by the recognizer. */ public void startListening(final Intent recognizerIntent) { + android.util.SeempLog.record(72); if (recognizerIntent == null) { throw new IllegalArgumentException("intent must not be null"); } diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index c6f73cb47576..3154acccc6d8 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -1099,6 +1099,9 @@ private boolean[] primaryIsTrailingPreviousAllLineOffsets(int line) { if (limit > lineEnd) { limit = lineEnd; } + if (limit == start) { + continue; + } level[limit - lineStart - 1] = (byte) ((runs[i + 1] >>> RUN_LEVEL_SHIFT) & RUN_LEVEL_MASK); } @@ -1194,8 +1197,8 @@ private float getHorizontal(int offset, boolean trailing, int line, boolean clam } /** - * Computes in linear time the results of calling - * #getHorizontal for all offsets on a line. + * Computes in linear time the results of calling #getHorizontal for all offsets on a line. + * * @param line The line giving the offsets we compute information for * @param clamped Whether to clamp the results to the width of the layout * @param primary Whether the results should be the primary or the secondary horizontal @@ -1230,7 +1233,7 @@ private float[] getLineHorizontals(int line, boolean clamped, boolean primary) { TextLine.recycle(tl); if (clamped) { - for (int offset = 0; offset <= wid.length; ++offset) { + for (int offset = 0; offset < wid.length; ++offset) { if (wid[offset] > mWidth) { wid[offset] = mWidth; } @@ -2277,7 +2280,10 @@ private void ellipsize(int start, int end, int line, final int ellipsisStringLen = ellipsisString.length(); // Use the ellipsis string only if there are that at least as many characters to replace. final boolean useEllipsisString = ellipsisCount >= ellipsisStringLen; - for (int i = 0; i < ellipsisCount; i++) { + final int min = Math.max(0, start - ellipsisStart - lineStart); + final int max = Math.min(ellipsisCount, end - ellipsisStart - lineStart); + + for (int i = min; i < max; i++) { final char c; if (useEllipsisString && i < ellipsisStringLen) { c = ellipsisString.charAt(i); @@ -2286,9 +2292,7 @@ private void ellipsize(int start, int end, int line, } final int a = i + ellipsisStart + lineStart; - if (start <= a && a < end) { - dest[destoff + a - start] = c; - } + dest[destoff + a - start] = c; } } diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 0899074174a2..40178d74d864 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -1325,12 +1325,12 @@ public int getEllipsizedWidth() { * @hide */ public int getHeight(boolean cap) { - if (cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight == -1 && + /*if (cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight == -1 && Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "maxLineHeight should not be -1. " + " maxLines:" + mMaximumVisibleLineCount + " lineCount:" + mLineCount); - } + }*/ return cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight != -1 ? mMaxLineHeight : super.getHeight(); diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 5bfd3e942934..04085dcaf283 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -256,10 +256,12 @@ void draw(Canvas c, float x, int top, int y, int bottom) { int lastRunIndex = runs.length - 2; for (int i = 0; i < runs.length; i += 2) { int runStart = runs[i]; + if (runStart > mLen) break; int runLimit = runStart + (runs[i+1] & Layout.RUN_LENGTH_MASK); if (runLimit > mLen) { runLimit = mLen; } + if (runStart > mLen) break; boolean runIsRtl = (runs[i+1] & Layout.RUN_RTL_FLAG) != 0; int segstart = runStart; @@ -334,10 +336,12 @@ float measure(int offset, boolean trailing, FontMetricsInt fmi) { int[] runs = mDirections.mDirections; for (int i = 0; i < runs.length; i += 2) { int runStart = runs[i]; + if (runStart > mLen) break; int runLimit = runStart + (runs[i+1] & Layout.RUN_LENGTH_MASK); if (runLimit > mLen) { runLimit = mLen; } + if (runStart > mLen) break; boolean runIsRtl = (runs[i+1] & Layout.RUN_RTL_FLAG) != 0; int segstart = runStart; @@ -423,10 +427,12 @@ float[] measureAllOffsets(boolean[] trailing, FontMetricsInt fmi) { int[] runs = mDirections.mDirections; for (int i = 0; i < runs.length; i += 2) { int runStart = runs[i]; + if (runStart > mLen) break; int runLimit = runStart + (runs[i + 1] & Layout.RUN_LENGTH_MASK); if (runLimit > mLen) { runLimit = mLen; } + if (runStart > mLen) break; boolean runIsRtl = (runs[i + 1] & Layout.RUN_RTL_FLAG) != 0; int segstart = runStart; diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 0f9ebee82c35..43ef2859a43a 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -42,7 +42,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_battery_display_app_list", "false"); DEFAULT_FLAGS.put("settings_zone_picker_v2", "true"); DEFAULT_FLAGS.put("settings_about_phone_v2", "true"); - DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "false"); + DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "true"); DEFAULT_FLAGS.put("settings_data_usage_v2", "true"); DEFAULT_FLAGS.put("settings_audio_switcher", "true"); DEFAULT_FLAGS.put("settings_systemui_theme", "true"); diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index 30d7b6c0786c..7191e305f214 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2018 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,20 +41,22 @@ public class NtpTrustedTime implements TrustedTime { private static NtpTrustedTime sSingleton; private static Context sContext; - private final String mServer; + private String mServer; private final long mTimeout; private ConnectivityManager mCM; private boolean mHasCache; + private final boolean mHasSecureServer; private long mCachedNtpTime; private long mCachedNtpElapsedRealtime; private long mCachedNtpCertainty; - private NtpTrustedTime(String server, long timeout) { + private NtpTrustedTime(String server, long timeout, boolean hasSecureServer) { if (LOGD) Log.d(TAG, "creating NtpTrustedTime using " + server); mServer = server; mTimeout = timeout; + mHasSecureServer = hasSecureServer; } public static synchronized NtpTrustedTime getInstance(Context context) { @@ -72,7 +75,7 @@ public static synchronized NtpTrustedTime getInstance(Context context) { resolver, Settings.Global.NTP_TIMEOUT, defaultTimeout); final String server = secureServer != null ? secureServer : defaultServer; - sSingleton = new NtpTrustedTime(server, timeout); + sSingleton = new NtpTrustedTime(server, timeout, secureServer != null); sContext = context; } @@ -114,6 +117,11 @@ public boolean forceRefresh(Network network) { if (LOGD) Log.d(TAG, "forceRefresh() from cache miss"); final SntpClient client = new SntpClient(); + if (!mHasSecureServer) { + mServer = sContext.getResources().getString( + com.android.internal.R.string.config_ntpServer); + if (LOGD) Log.d(TAG, "NTP server changed to " + mServer); + } if (client.requestTime(mServer, (int) mTimeout, network)) { mHasCache = true; mCachedNtpTime = client.getNtpTime(); diff --git a/core/java/android/util/SeempLog.java b/core/java/android/util/SeempLog.java new file mode 100644 index 000000000000..3764882644d8 --- /dev/null +++ b/core/java/android/util/SeempLog.java @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package android.util; + +import com.android.internal.os.RuntimeInit; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.UnknownHostException; +import java.util.Hashtable; +import java.util.Map; +import java.util.List; +import java.util.Iterator; +import android.util.Log; +import android.provider.Settings; + +/** + * SeempLog + * + * @hide + */ +public final class SeempLog { + private SeempLog() { + } + + /** + * Send a log message to the seemp log. + * @param api The api triggering this message. + */ + public static int record(int api) { + return seemp_println_native(api, ""); + } + + /** + * Send a log message to the seemp log. + * @param api The api triggering this message. + * @param msg The message you would like logged. + */ + public static int record_str(int api, String msg) { + if ( msg != null ) { + return seemp_println_native(api, msg); + } + else { + return seemp_println_native(api, ""); + } + } + + public static int record_sensor(int api, + android.hardware.Sensor sensor) { + if ( sensor != null ) { + return seemp_println_native(api, "sensor="+sensor.getType()); + } + else { + return seemp_println_native(api, "sensor=-1"); + } + } + + public static int record_sensor_rate(int api, + android.hardware.Sensor sensor, int rate) { + if ( sensor != null ) { + return seemp_println_native(api, + "sensor="+sensor.getType() + ",rate="+rate); + } + else { + return seemp_println_native(api, "sensor=-1,rate=" + rate); + } + } + + public static int record_uri(int api, android.net.Uri uri) { + if ( uri != null ) { + return seemp_println_native(api, "uri, " + uri.toString()); + } + else { + return seemp_println_native(api, "uri, null" ); + } + } + + public static int record_vg_layout(int api, + android.view.ViewGroup.LayoutParams params) { + try { + android.view.WindowManager.LayoutParams p = + (android.view.WindowManager.LayoutParams) params; + if ( p != null ) { + return seemp_println_native(api, + "window_type=" + p.type + ",window_flag=" + p.flags); + } + else { + return seemp_println_native(api, ""); + } + } catch (ClassCastException cce) { + return seemp_println_native(api, ""); + } + } + + /** @hide */ public static native int seemp_println_native(int api, String msg); + + public static final int SEEMP_API_android_provider_Settings__get_ANDROID_ID_ = 7; + public static final int SEEMP_API_android_provider_Settings__get_ACCELEROMETER_ROTATION_ = 96; + public static final int SEEMP_API_android_provider_Settings__get_USER_ROTATION_ = 97; + public static final int SEEMP_API_android_provider_Settings__get_ADB_ENABLED_ = 98; + public static final int SEEMP_API_android_provider_Settings__get_DEBUG_APP_ = 99; + public static final int SEEMP_API_android_provider_Settings__get_WAIT_FOR_DEBUGGER_ = 100; + public static final int SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_ON_ = 101; + public static final int SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_RADIOS_ = 102; + public static final int SEEMP_API_android_provider_Settings__get_ALARM_ALERT_ = 103; + public static final int SEEMP_API_android_provider_Settings__get_NEXT_ALARM_FORMATTED_ = 104; + public static final int SEEMP_API_android_provider_Settings__get_ALWAYS_FINISH_ACTIVITIES_ = 105; + public static final int SEEMP_API_android_provider_Settings__get_LOGGING_ID_ = 106; + public static final int SEEMP_API_android_provider_Settings__get_ANIMATOR_DURATION_SCALE_ = 107; + public static final int SEEMP_API_android_provider_Settings__get_WINDOW_ANIMATION_SCALE_ = 108; + public static final int SEEMP_API_android_provider_Settings__get_FONT_SCALE_ = 109; + public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_ = 110; + public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_ = 111; + public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ = 112; + public static final int SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_MANUAL_ = 113; + public static final int SEEMP_API_android_provider_Settings__get_SCREEN_OFF_TIMEOUT_ = 114; + public static final int SEEMP_API_android_provider_Settings__get_DIM_SCREEN_ = 115; + public static final int SEEMP_API_android_provider_Settings__get_TRANSITION_ANIMATION_SCALE_ = 116; + public static final int SEEMP_API_android_provider_Settings__get_STAY_ON_WHILE_PLUGGED_IN_ = 117; + public static final int SEEMP_API_android_provider_Settings__get_WALLPAPER_ACTIVITY_ = 118; + public static final int SEEMP_API_android_provider_Settings__get_SHOW_PROCESSES_ = 119; + public static final int SEEMP_API_android_provider_Settings__get_SHOW_WEB_SUGGESTIONS_ = 120; + public static final int SEEMP_API_android_provider_Settings__get_SHOW_GTALK_SERVICE_STATUS_ = 121; + public static final int SEEMP_API_android_provider_Settings__get_USE_GOOGLE_MAIL_ = 122; + public static final int SEEMP_API_android_provider_Settings__get_AUTO_TIME_ = 123; + public static final int SEEMP_API_android_provider_Settings__get_AUTO_TIME_ZONE_ = 124; + public static final int SEEMP_API_android_provider_Settings__get_DATE_FORMAT_ = 125; + public static final int SEEMP_API_android_provider_Settings__get_TIME_12_24_ = 126; + public static final int SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_ = 127; + public static final int SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ = 128; + public static final int SEEMP_API_android_provider_Settings__get_BLUETOOTH_ON_ = 129; + public static final int SEEMP_API_android_provider_Settings__get_DEVICE_PROVISIONED_ = 130; + public static final int SEEMP_API_android_provider_Settings__get_SETUP_WIZARD_HAS_RUN_ = 131; + public static final int SEEMP_API_android_provider_Settings__get_DTMF_TONE_WHEN_DIALING_ = 132; + public static final int SEEMP_API_android_provider_Settings__get_END_BUTTON_BEHAVIOR_ = 133; + public static final int SEEMP_API_android_provider_Settings__get_RINGTONE_ = 134; + public static final int SEEMP_API_android_provider_Settings__get_MODE_RINGER_ = 135; + public static final int SEEMP_API_android_provider_Settings__get_INSTALL_NON_MARKET_APPS_ = 136; + public static final int SEEMP_API_android_provider_Settings__get_LOCATION_PROVIDERS_ALLOWED_ = 137; + public static final int SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_ENABLED_ = 138; + public static final int SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ = 139; + public static final int SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_VISIBLE_ = 140; + public static final int SEEMP_API_android_provider_Settings__get_NETWORK_PREFERENCE_ = 141; + public static final int SEEMP_API_android_provider_Settings__get_DATA_ROAMING_ = 142; + public static final int SEEMP_API_android_provider_Settings__get_HTTP_PROXY_ = 143; + public static final int SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_ENABLED_ = 144; + public static final int SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_LAST_UPDATE_ = 145; + public static final int SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_REDIRECT_URL_ = 146; + public static final int SEEMP_API_android_provider_Settings__get_RADIO_BLUETOOTH_ = 147; + public static final int SEEMP_API_android_provider_Settings__get_RADIO_CELL_ = 148; + public static final int SEEMP_API_android_provider_Settings__get_RADIO_NFC_ = 149; + public static final int SEEMP_API_android_provider_Settings__get_RADIO_WIFI_ = 150; + public static final int SEEMP_API_android_provider_Settings__get_SYS_PROP_SETTING_VERSION_ = 151; + public static final int SEEMP_API_android_provider_Settings__get_SETTINGS_CLASSNAME_ = 152; + public static final int SEEMP_API_android_provider_Settings__get_TEXT_AUTO_CAPS_ = 153; + public static final int SEEMP_API_android_provider_Settings__get_TEXT_AUTO_PUNCTUATE_ = 154; + public static final int SEEMP_API_android_provider_Settings__get_TEXT_AUTO_REPLACE_ = 155; + public static final int SEEMP_API_android_provider_Settings__get_TEXT_SHOW_PASSWORD_ = 156; + public static final int SEEMP_API_android_provider_Settings__get_USB_MASS_STORAGE_ENABLED_ = 157; + public static final int SEEMP_API_android_provider_Settings__get_VIBRATE_ON_ = 158; + public static final int SEEMP_API_android_provider_Settings__get_HAPTIC_FEEDBACK_ENABLED_ = 159; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_ALARM_ = 160; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_BLUETOOTH_SCO_ = 161; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_MUSIC_ = 162; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_NOTIFICATION_ = 163; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_RING_ = 164; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_SYSTEM_ = 165; + public static final int SEEMP_API_android_provider_Settings__get_VOLUME_VOICE_ = 166; + public static final int SEEMP_API_android_provider_Settings__get_SOUND_EFFECTS_ENABLED_ = 167; + public static final int SEEMP_API_android_provider_Settings__get_MODE_RINGER_STREAMS_AFFECTED_ = 168; + public static final int SEEMP_API_android_provider_Settings__get_MUTE_STREAMS_AFFECTED_ = 169; + public static final int SEEMP_API_android_provider_Settings__get_NOTIFICATION_SOUND_ = 170; + public static final int SEEMP_API_android_provider_Settings__get_APPEND_FOR_LAST_AUDIBLE_ = 171; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_MAX_DHCP_RETRY_COUNT_ = 172; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_ = 173; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ = 174; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ = 175; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_NUM_OPEN_NETWORKS_KEPT_ = 176; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_ON_ = 177; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_ = 178; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_DEFAULT_ = 179; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_NEVER_ = 180; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ = 181; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS1_ = 182; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS2_ = 183; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_GATEWAY_ = 184; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_IP_ = 185; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_STATIC_NETMASK_ = 186; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_USE_STATIC_IP_ = 187; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_ = 188; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_AP_COUNT_ = 189; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ = 190; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ = 191; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ = 192; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ = 193; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_MAX_AP_CHECKS_ = 194; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ON_ = 195; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_COUNT_ = 196; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_DELAY_MS_ = 197; + public static final int SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_TIMEOUT_MS_ = 198; + public static final int SEEMP_API_android_provider_Settings__put_ACCELEROMETER_ROTATION_ = 199; + public static final int SEEMP_API_android_provider_Settings__put_USER_ROTATION_ = 200; + public static final int SEEMP_API_android_provider_Settings__put_ADB_ENABLED_ = 201; + public static final int SEEMP_API_android_provider_Settings__put_DEBUG_APP_ = 202; + public static final int SEEMP_API_android_provider_Settings__put_WAIT_FOR_DEBUGGER_ = 203; + public static final int SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_ON_ = 204; + public static final int SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_RADIOS_ = 205; + public static final int SEEMP_API_android_provider_Settings__put_ALARM_ALERT_ = 206; + public static final int SEEMP_API_android_provider_Settings__put_NEXT_ALARM_FORMATTED_ = 207; + public static final int SEEMP_API_android_provider_Settings__put_ALWAYS_FINISH_ACTIVITIES_ = 208; + public static final int SEEMP_API_android_provider_Settings__put_ANDROID_ID_ = 209; + public static final int SEEMP_API_android_provider_Settings__put_LOGGING_ID_ = 210; + public static final int SEEMP_API_android_provider_Settings__put_ANIMATOR_DURATION_SCALE_ = 211; + public static final int SEEMP_API_android_provider_Settings__put_WINDOW_ANIMATION_SCALE_ = 212; + public static final int SEEMP_API_android_provider_Settings__put_FONT_SCALE_ = 213; + public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_ = 214; + public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_ = 215; + public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ = 216; + public static final int SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_MANUAL_ = 217; + public static final int SEEMP_API_android_provider_Settings__put_SCREEN_OFF_TIMEOUT_ = 218; + public static final int SEEMP_API_android_provider_Settings__put_DIM_SCREEN_ = 219; + public static final int SEEMP_API_android_provider_Settings__put_TRANSITION_ANIMATION_SCALE_ = 220; + public static final int SEEMP_API_android_provider_Settings__put_STAY_ON_WHILE_PLUGGED_IN_ = 221; + public static final int SEEMP_API_android_provider_Settings__put_WALLPAPER_ACTIVITY_ = 222; + public static final int SEEMP_API_android_provider_Settings__put_SHOW_PROCESSES_ = 223; + public static final int SEEMP_API_android_provider_Settings__put_SHOW_WEB_SUGGESTIONS_ = 224; + public static final int SEEMP_API_android_provider_Settings__put_SHOW_GTALK_SERVICE_STATUS_ = 225; + public static final int SEEMP_API_android_provider_Settings__put_USE_GOOGLE_MAIL_ = 226; + public static final int SEEMP_API_android_provider_Settings__put_AUTO_TIME_ = 227; + public static final int SEEMP_API_android_provider_Settings__put_AUTO_TIME_ZONE_ = 228; + public static final int SEEMP_API_android_provider_Settings__put_DATE_FORMAT_ = 229; + public static final int SEEMP_API_android_provider_Settings__put_TIME_12_24_ = 230; + public static final int SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_ = 231; + public static final int SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ = 232; + public static final int SEEMP_API_android_provider_Settings__put_BLUETOOTH_ON_ = 233; + public static final int SEEMP_API_android_provider_Settings__put_DEVICE_PROVISIONED_ = 234; + public static final int SEEMP_API_android_provider_Settings__put_SETUP_WIZARD_HAS_RUN_ = 235; + public static final int SEEMP_API_android_provider_Settings__put_DTMF_TONE_WHEN_DIALING_ = 236; + public static final int SEEMP_API_android_provider_Settings__put_END_BUTTON_BEHAVIOR_ = 237; + public static final int SEEMP_API_android_provider_Settings__put_RINGTONE_ = 238; + public static final int SEEMP_API_android_provider_Settings__put_MODE_RINGER_ = 239; + public static final int SEEMP_API_android_provider_Settings__put_INSTALL_NON_MARKET_APPS_ = 240; + public static final int SEEMP_API_android_provider_Settings__put_LOCATION_PROVIDERS_ALLOWED_ = 241; + public static final int SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_ENABLED_ = 242; + public static final int SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ = 243; + public static final int SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_VISIBLE_ = 244; + public static final int SEEMP_API_android_provider_Settings__put_NETWORK_PREFERENCE_ = 245; + public static final int SEEMP_API_android_provider_Settings__put_DATA_ROAMING_ = 246; + public static final int SEEMP_API_android_provider_Settings__put_HTTP_PROXY_ = 247; + public static final int SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_ENABLED_ = 248; + public static final int SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_LAST_UPDATE_ = 249; + public static final int SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_REDIRECT_URL_ = 250; + public static final int SEEMP_API_android_provider_Settings__put_RADIO_BLUETOOTH_ = 251; + public static final int SEEMP_API_android_provider_Settings__put_RADIO_CELL_ = 252; + public static final int SEEMP_API_android_provider_Settings__put_RADIO_NFC_ = 253; + public static final int SEEMP_API_android_provider_Settings__put_RADIO_WIFI_ = 254; + public static final int SEEMP_API_android_provider_Settings__put_SYS_PROP_SETTING_VERSION_ = 255; + public static final int SEEMP_API_android_provider_Settings__put_SETTINGS_CLASSNAME_ = 256; + public static final int SEEMP_API_android_provider_Settings__put_TEXT_AUTO_CAPS_ = 257; + public static final int SEEMP_API_android_provider_Settings__put_TEXT_AUTO_PUNCTUATE_ = 258; + public static final int SEEMP_API_android_provider_Settings__put_TEXT_AUTO_REPLACE_ = 259; + public static final int SEEMP_API_android_provider_Settings__put_TEXT_SHOW_PASSWORD_ = 260; + public static final int SEEMP_API_android_provider_Settings__put_USB_MASS_STORAGE_ENABLED_ = 261; + public static final int SEEMP_API_android_provider_Settings__put_VIBRATE_ON_ = 262; + public static final int SEEMP_API_android_provider_Settings__put_HAPTIC_FEEDBACK_ENABLED_ = 263; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_ALARM_ = 264; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_BLUETOOTH_SCO_ = 265; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_MUSIC_ = 266; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_NOTIFICATION_ = 267; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_RING_ = 268; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_SYSTEM_ = 269; + public static final int SEEMP_API_android_provider_Settings__put_VOLUME_VOICE_ = 270; + public static final int SEEMP_API_android_provider_Settings__put_SOUND_EFFECTS_ENABLED_ = 271; + public static final int SEEMP_API_android_provider_Settings__put_MODE_RINGER_STREAMS_AFFECTED_ = 272; + public static final int SEEMP_API_android_provider_Settings__put_MUTE_STREAMS_AFFECTED_ = 273; + public static final int SEEMP_API_android_provider_Settings__put_NOTIFICATION_SOUND_ = 274; + public static final int SEEMP_API_android_provider_Settings__put_APPEND_FOR_LAST_AUDIBLE_ = 275; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_MAX_DHCP_RETRY_COUNT_ = 276; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_ = 277; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ = 278; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ = 279; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_NUM_OPEN_NETWORKS_KEPT_ = 280; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_ON_ = 281; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_ = 282; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_DEFAULT_ = 283; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_NEVER_ = 284; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ = 285; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS1_ = 286; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS2_ = 287; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_GATEWAY_ = 288; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_IP_ = 289; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_STATIC_NETMASK_ = 290; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_USE_STATIC_IP_ = 291; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_ = 292; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_AP_COUNT_ = 293; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ = 294; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ = 295; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ = 296; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ = 297; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_MAX_AP_CHECKS_ = 298; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ON_ = 299; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_COUNT_ = 300; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_DELAY_MS_ = 301; + public static final int SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_TIMEOUT_MS_ = 302; + + private final static java.util.Map value_to_get_map; + static { + value_to_get_map = new java.util.HashMap( 198 ); + value_to_get_map.put(Settings.System.NOTIFICATION_SOUND, + SEEMP_API_android_provider_Settings__get_NOTIFICATION_SOUND_); + value_to_get_map.put(Settings.System.DTMF_TONE_WHEN_DIALING, + SEEMP_API_android_provider_Settings__get_DTMF_TONE_WHEN_DIALING_); + value_to_get_map.put(Settings.System.LOCK_PATTERN_ENABLED, + SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_ENABLED_); + value_to_get_map.put(Settings.System.WIFI_MAX_DHCP_RETRY_COUNT, + SEEMP_API_android_provider_Settings__get_WIFI_MAX_DHCP_RETRY_COUNT_); + value_to_get_map.put(Settings.System.AUTO_TIME, + SEEMP_API_android_provider_Settings__get_AUTO_TIME_); + value_to_get_map.put(Settings.System.SETUP_WIZARD_HAS_RUN, + SEEMP_API_android_provider_Settings__get_SETUP_WIZARD_HAS_RUN_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_); + value_to_get_map.put(Settings.System.LOCATION_PROVIDERS_ALLOWED, + SEEMP_API_android_provider_Settings__get_LOCATION_PROVIDERS_ALLOWED_); + value_to_get_map.put(Settings.System.ALARM_ALERT, + SEEMP_API_android_provider_Settings__get_ALARM_ALERT_); + value_to_get_map.put(Settings.System.VIBRATE_ON, + SEEMP_API_android_provider_Settings__get_VIBRATE_ON_); + value_to_get_map.put(Settings.System.USB_MASS_STORAGE_ENABLED, + SEEMP_API_android_provider_Settings__get_USB_MASS_STORAGE_ENABLED_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_PING_DELAY_MS, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_DELAY_MS_); + value_to_get_map.put(Settings.System.FONT_SCALE, + SEEMP_API_android_provider_Settings__get_FONT_SCALE_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_AP_COUNT, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_AP_COUNT_); + value_to_get_map.put(Settings.System.ALWAYS_FINISH_ACTIVITIES, + SEEMP_API_android_provider_Settings__get_ALWAYS_FINISH_ACTIVITIES_); + value_to_get_map.put(Settings.System.ACCELEROMETER_ROTATION, + SEEMP_API_android_provider_Settings__get_ACCELEROMETER_ROTATION_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_PING_TIMEOUT_MS, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_TIMEOUT_MS_); + value_to_get_map.put(Settings.System.VOLUME_NOTIFICATION, + SEEMP_API_android_provider_Settings__get_VOLUME_NOTIFICATION_); + value_to_get_map.put(Settings.System.AIRPLANE_MODE_ON, + SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_ON_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_); + value_to_get_map.put(Settings.System.WIFI_STATIC_IP, + SEEMP_API_android_provider_Settings__get_WIFI_STATIC_IP_); + value_to_get_map.put(Settings.System.RADIO_BLUETOOTH, + SEEMP_API_android_provider_Settings__get_RADIO_BLUETOOTH_); + value_to_get_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT, + SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_TIMEOUT_); + value_to_get_map.put(Settings.System.VOLUME_RING, + SEEMP_API_android_provider_Settings__get_VOLUME_RING_); + value_to_get_map.put(Settings.System.MODE_RINGER_STREAMS_AFFECTED, + SEEMP_API_android_provider_Settings__get_MODE_RINGER_STREAMS_AFFECTED_); + value_to_get_map.put(Settings.System.VOLUME_SYSTEM, + SEEMP_API_android_provider_Settings__get_VOLUME_SYSTEM_); + value_to_get_map.put(Settings.System.SCREEN_OFF_TIMEOUT, + SEEMP_API_android_provider_Settings__get_SCREEN_OFF_TIMEOUT_); + value_to_get_map.put(Settings.System.RADIO_WIFI, + SEEMP_API_android_provider_Settings__get_RADIO_WIFI_); + value_to_get_map.put(Settings.System.AUTO_TIME_ZONE, + SEEMP_API_android_provider_Settings__get_AUTO_TIME_ZONE_); + value_to_get_map.put(Settings.System.TEXT_AUTO_CAPS, + SEEMP_API_android_provider_Settings__get_TEXT_AUTO_CAPS_); + value_to_get_map.put(Settings.System.WALLPAPER_ACTIVITY, + SEEMP_API_android_provider_Settings__get_WALLPAPER_ACTIVITY_); + value_to_get_map.put(Settings.System.ANIMATOR_DURATION_SCALE, + SEEMP_API_android_provider_Settings__get_ANIMATOR_DURATION_SCALE_); + value_to_get_map.put(Settings.System.WIFI_NUM_OPEN_NETWORKS_KEPT, + SEEMP_API_android_provider_Settings__get_WIFI_NUM_OPEN_NETWORKS_KEPT_); + value_to_get_map.put(Settings.System.LOCK_PATTERN_VISIBLE, + SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_VISIBLE_); + value_to_get_map.put(Settings.System.VOLUME_VOICE, + SEEMP_API_android_provider_Settings__get_VOLUME_VOICE_); + value_to_get_map.put(Settings.System.DEBUG_APP, + SEEMP_API_android_provider_Settings__get_DEBUG_APP_); + value_to_get_map.put(Settings.System.WIFI_ON, + SEEMP_API_android_provider_Settings__get_WIFI_ON_); + value_to_get_map.put(Settings.System.TEXT_SHOW_PASSWORD, + SEEMP_API_android_provider_Settings__get_TEXT_SHOW_PASSWORD_); + value_to_get_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, + SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_); + value_to_get_map.put(Settings.System.WIFI_SLEEP_POLICY, + SEEMP_API_android_provider_Settings__get_WIFI_SLEEP_POLICY_); + value_to_get_map.put(Settings.System.VOLUME_MUSIC, + SEEMP_API_android_provider_Settings__get_VOLUME_MUSIC_); + value_to_get_map.put(Settings.System.PARENTAL_CONTROL_LAST_UPDATE, + SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_LAST_UPDATE_); + value_to_get_map.put(Settings.System.DEVICE_PROVISIONED, + SEEMP_API_android_provider_Settings__get_DEVICE_PROVISIONED_); + value_to_get_map.put(Settings.System.HTTP_PROXY, + SEEMP_API_android_provider_Settings__get_HTTP_PROXY_); + value_to_get_map.put(Settings.System.ANDROID_ID, + SEEMP_API_android_provider_Settings__get_ANDROID_ID_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_MAX_AP_CHECKS, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_MAX_AP_CHECKS_); + value_to_get_map.put(Settings.System.END_BUTTON_BEHAVIOR, + SEEMP_API_android_provider_Settings__get_END_BUTTON_BEHAVIOR_); + value_to_get_map.put(Settings.System.NEXT_ALARM_FORMATTED, + SEEMP_API_android_provider_Settings__get_NEXT_ALARM_FORMATTED_); + value_to_get_map.put(Settings.System.RADIO_CELL, + SEEMP_API_android_provider_Settings__get_RADIO_CELL_); + value_to_get_map.put(Settings.System.PARENTAL_CONTROL_ENABLED, + SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_ENABLED_); + value_to_get_map.put(Settings.System.BLUETOOTH_ON, + SEEMP_API_android_provider_Settings__get_BLUETOOTH_ON_); + value_to_get_map.put(Settings.System.WINDOW_ANIMATION_SCALE, + SEEMP_API_android_provider_Settings__get_WINDOW_ANIMATION_SCALE_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_); + value_to_get_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY, + SEEMP_API_android_provider_Settings__get_BLUETOOTH_DISCOVERABILITY_); + value_to_get_map.put(Settings.System.WIFI_STATIC_DNS1, + SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS1_); + value_to_get_map.put(Settings.System.WIFI_STATIC_DNS2, + SEEMP_API_android_provider_Settings__get_WIFI_STATIC_DNS2_); + value_to_get_map.put(Settings.System.HAPTIC_FEEDBACK_ENABLED, + SEEMP_API_android_provider_Settings__get_HAPTIC_FEEDBACK_ENABLED_); + value_to_get_map.put(Settings.System.SHOW_WEB_SUGGESTIONS, + SEEMP_API_android_provider_Settings__get_SHOW_WEB_SUGGESTIONS_); + value_to_get_map.put(Settings.System.PARENTAL_CONTROL_REDIRECT_URL, + SEEMP_API_android_provider_Settings__get_PARENTAL_CONTROL_REDIRECT_URL_); + value_to_get_map.put(Settings.System.DATE_FORMAT, + SEEMP_API_android_provider_Settings__get_DATE_FORMAT_); + value_to_get_map.put(Settings.System.RADIO_NFC, + SEEMP_API_android_provider_Settings__get_RADIO_NFC_); + value_to_get_map.put(Settings.System.AIRPLANE_MODE_RADIOS, + SEEMP_API_android_provider_Settings__get_AIRPLANE_MODE_RADIOS_); + value_to_get_map.put(Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, + SEEMP_API_android_provider_Settings__get_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_); + value_to_get_map.put(Settings.System.TIME_12_24, + SEEMP_API_android_provider_Settings__get_TIME_12_24_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_); + value_to_get_map.put(Settings.System.VOLUME_BLUETOOTH_SCO, + SEEMP_API_android_provider_Settings__get_VOLUME_BLUETOOTH_SCO_); + value_to_get_map.put(Settings.System.USER_ROTATION, + SEEMP_API_android_provider_Settings__get_USER_ROTATION_); + value_to_get_map.put(Settings.System.WIFI_STATIC_GATEWAY, + SEEMP_API_android_provider_Settings__get_WIFI_STATIC_GATEWAY_); + value_to_get_map.put(Settings.System.STAY_ON_WHILE_PLUGGED_IN, + SEEMP_API_android_provider_Settings__get_STAY_ON_WHILE_PLUGGED_IN_); + value_to_get_map.put(Settings.System.SOUND_EFFECTS_ENABLED, + SEEMP_API_android_provider_Settings__get_SOUND_EFFECTS_ENABLED_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_PING_COUNT, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_PING_COUNT_); + value_to_get_map.put(Settings.System.DATA_ROAMING, + SEEMP_API_android_provider_Settings__get_DATA_ROAMING_); + value_to_get_map.put(Settings.System.SETTINGS_CLASSNAME, + SEEMP_API_android_provider_Settings__get_SETTINGS_CLASSNAME_); + value_to_get_map.put(Settings.System.TRANSITION_ANIMATION_SCALE, + SEEMP_API_android_provider_Settings__get_TRANSITION_ANIMATION_SCALE_); + value_to_get_map.put(Settings.System.WAIT_FOR_DEBUGGER, + SEEMP_API_android_provider_Settings__get_WAIT_FOR_DEBUGGER_); + value_to_get_map.put(Settings.System.INSTALL_NON_MARKET_APPS, + SEEMP_API_android_provider_Settings__get_INSTALL_NON_MARKET_APPS_); + value_to_get_map.put(Settings.System.ADB_ENABLED, + SEEMP_API_android_provider_Settings__get_ADB_ENABLED_); + value_to_get_map.put(Settings.System.WIFI_USE_STATIC_IP, + SEEMP_API_android_provider_Settings__get_WIFI_USE_STATIC_IP_); + value_to_get_map.put(Settings.System.DIM_SCREEN, + SEEMP_API_android_provider_Settings__get_DIM_SCREEN_); + value_to_get_map.put(Settings.System.VOLUME_ALARM, + SEEMP_API_android_provider_Settings__get_VOLUME_ALARM_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_ON, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ON_); + value_to_get_map.put(Settings.System.WIFI_STATIC_NETMASK, + SEEMP_API_android_provider_Settings__get_WIFI_STATIC_NETMASK_); + value_to_get_map.put(Settings.System.NETWORK_PREFERENCE, + SEEMP_API_android_provider_Settings__get_NETWORK_PREFERENCE_); + value_to_get_map.put(Settings.System.SHOW_PROCESSES, + SEEMP_API_android_provider_Settings__get_SHOW_PROCESSES_); + value_to_get_map.put(Settings.System.TEXT_AUTO_REPLACE, + SEEMP_API_android_provider_Settings__get_TEXT_AUTO_REPLACE_); + value_to_get_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, + SEEMP_API_android_provider_Settings__get_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_); + value_to_get_map.put(Settings.System.APPEND_FOR_LAST_AUDIBLE, + SEEMP_API_android_provider_Settings__get_APPEND_FOR_LAST_AUDIBLE_); + value_to_get_map.put(Settings.System.SHOW_GTALK_SERVICE_STATUS, + SEEMP_API_android_provider_Settings__get_SHOW_GTALK_SERVICE_STATUS_); + value_to_get_map.put(Settings.System.SCREEN_BRIGHTNESS, + SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_); + value_to_get_map.put(Settings.System.USE_GOOGLE_MAIL, + SEEMP_API_android_provider_Settings__get_USE_GOOGLE_MAIL_); + value_to_get_map.put(Settings.System.RINGTONE, + SEEMP_API_android_provider_Settings__get_RINGTONE_); + value_to_get_map.put(Settings.System.LOGGING_ID, + SEEMP_API_android_provider_Settings__get_LOGGING_ID_); + value_to_get_map.put(Settings.System.MODE_RINGER, + SEEMP_API_android_provider_Settings__get_MODE_RINGER_); + value_to_get_map.put(Settings.System.MUTE_STREAMS_AFFECTED, + SEEMP_API_android_provider_Settings__get_MUTE_STREAMS_AFFECTED_); + value_to_get_map.put(Settings.System.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE, + SEEMP_API_android_provider_Settings__get_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_); + value_to_get_map.put(Settings.System.TEXT_AUTO_PUNCTUATE, + SEEMP_API_android_provider_Settings__get_TEXT_AUTO_PUNCTUATE_); + value_to_get_map.put(Settings.System.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS, + SEEMP_API_android_provider_Settings__get_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_); + value_to_get_map.put(Settings.System.SCREEN_BRIGHTNESS_MODE, + SEEMP_API_android_provider_Settings__get_SCREEN_BRIGHTNESS_MODE_); + } + + public static int getSeempGetApiIdFromValue( String v ) + { + Integer result = value_to_get_map.get( v ); + if (result == null) + { + result = -1; + } + return result; + } + + private final static java.util.Map value_to_put_map; + static { + value_to_put_map = new java.util.HashMap( 198 ); + value_to_put_map.put(Settings.System.NOTIFICATION_SOUND, + SEEMP_API_android_provider_Settings__put_NOTIFICATION_SOUND_); + value_to_put_map.put(Settings.System.DTMF_TONE_WHEN_DIALING, + SEEMP_API_android_provider_Settings__put_DTMF_TONE_WHEN_DIALING_); + value_to_put_map.put(Settings.System.LOCK_PATTERN_ENABLED, + SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_ENABLED_); + value_to_put_map.put(Settings.System.WIFI_MAX_DHCP_RETRY_COUNT, + SEEMP_API_android_provider_Settings__put_WIFI_MAX_DHCP_RETRY_COUNT_); + value_to_put_map.put(Settings.System.AUTO_TIME, + SEEMP_API_android_provider_Settings__put_AUTO_TIME_); + value_to_put_map.put(Settings.System.SETUP_WIZARD_HAS_RUN, + SEEMP_API_android_provider_Settings__put_SETUP_WIZARD_HAS_RUN_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_); + value_to_put_map.put(Settings.System.LOCATION_PROVIDERS_ALLOWED, + SEEMP_API_android_provider_Settings__put_LOCATION_PROVIDERS_ALLOWED_); + value_to_put_map.put(Settings.System.ALARM_ALERT, + SEEMP_API_android_provider_Settings__put_ALARM_ALERT_); + value_to_put_map.put(Settings.System.VIBRATE_ON, + SEEMP_API_android_provider_Settings__put_VIBRATE_ON_); + value_to_put_map.put(Settings.System.USB_MASS_STORAGE_ENABLED, + SEEMP_API_android_provider_Settings__put_USB_MASS_STORAGE_ENABLED_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_PING_DELAY_MS, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_DELAY_MS_); + value_to_put_map.put(Settings.System.FONT_SCALE, + SEEMP_API_android_provider_Settings__put_FONT_SCALE_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_AP_COUNT, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_AP_COUNT_); + value_to_put_map.put(Settings.System.ALWAYS_FINISH_ACTIVITIES, + SEEMP_API_android_provider_Settings__put_ALWAYS_FINISH_ACTIVITIES_); + value_to_put_map.put(Settings.System.ACCELEROMETER_ROTATION, + SEEMP_API_android_provider_Settings__put_ACCELEROMETER_ROTATION_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_PING_TIMEOUT_MS, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_TIMEOUT_MS_); + value_to_put_map.put(Settings.System.VOLUME_NOTIFICATION, + SEEMP_API_android_provider_Settings__put_VOLUME_NOTIFICATION_); + value_to_put_map.put(Settings.System.AIRPLANE_MODE_ON, + SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_ON_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_); + value_to_put_map.put(Settings.System.WIFI_STATIC_IP, + SEEMP_API_android_provider_Settings__put_WIFI_STATIC_IP_); + value_to_put_map.put(Settings.System.RADIO_BLUETOOTH, + SEEMP_API_android_provider_Settings__put_RADIO_BLUETOOTH_); + value_to_put_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT, + SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_TIMEOUT_); + value_to_put_map.put(Settings.System.VOLUME_RING, + SEEMP_API_android_provider_Settings__put_VOLUME_RING_); + value_to_put_map.put(Settings.System.MODE_RINGER_STREAMS_AFFECTED, + SEEMP_API_android_provider_Settings__put_MODE_RINGER_STREAMS_AFFECTED_); + value_to_put_map.put(Settings.System.VOLUME_SYSTEM, + SEEMP_API_android_provider_Settings__put_VOLUME_SYSTEM_); + value_to_put_map.put(Settings.System.SCREEN_OFF_TIMEOUT, + SEEMP_API_android_provider_Settings__put_SCREEN_OFF_TIMEOUT_); + value_to_put_map.put(Settings.System.RADIO_WIFI, + SEEMP_API_android_provider_Settings__put_RADIO_WIFI_); + value_to_put_map.put(Settings.System.AUTO_TIME_ZONE, + SEEMP_API_android_provider_Settings__put_AUTO_TIME_ZONE_); + value_to_put_map.put(Settings.System.TEXT_AUTO_CAPS, + SEEMP_API_android_provider_Settings__put_TEXT_AUTO_CAPS_); + value_to_put_map.put(Settings.System.WALLPAPER_ACTIVITY, + SEEMP_API_android_provider_Settings__put_WALLPAPER_ACTIVITY_); + value_to_put_map.put(Settings.System.ANIMATOR_DURATION_SCALE, + SEEMP_API_android_provider_Settings__put_ANIMATOR_DURATION_SCALE_); + value_to_put_map.put(Settings.System.WIFI_NUM_OPEN_NETWORKS_KEPT, + SEEMP_API_android_provider_Settings__put_WIFI_NUM_OPEN_NETWORKS_KEPT_); + value_to_put_map.put(Settings.System.LOCK_PATTERN_VISIBLE, + SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_VISIBLE_); + value_to_put_map.put(Settings.System.VOLUME_VOICE, + SEEMP_API_android_provider_Settings__put_VOLUME_VOICE_); + value_to_put_map.put(Settings.System.DEBUG_APP, + SEEMP_API_android_provider_Settings__put_DEBUG_APP_); + value_to_put_map.put(Settings.System.WIFI_ON, + SEEMP_API_android_provider_Settings__put_WIFI_ON_); + value_to_put_map.put(Settings.System.TEXT_SHOW_PASSWORD, + SEEMP_API_android_provider_Settings__put_TEXT_SHOW_PASSWORD_); + value_to_put_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, + SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_); + value_to_put_map.put(Settings.System.WIFI_SLEEP_POLICY, + SEEMP_API_android_provider_Settings__put_WIFI_SLEEP_POLICY_); + value_to_put_map.put(Settings.System.VOLUME_MUSIC, + SEEMP_API_android_provider_Settings__put_VOLUME_MUSIC_); + value_to_put_map.put(Settings.System.PARENTAL_CONTROL_LAST_UPDATE, + SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_LAST_UPDATE_); + value_to_put_map.put(Settings.System.DEVICE_PROVISIONED, + SEEMP_API_android_provider_Settings__put_DEVICE_PROVISIONED_); + value_to_put_map.put(Settings.System.HTTP_PROXY, + SEEMP_API_android_provider_Settings__put_HTTP_PROXY_); + value_to_put_map.put(Settings.System.ANDROID_ID, + SEEMP_API_android_provider_Settings__put_ANDROID_ID_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_MAX_AP_CHECKS, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_MAX_AP_CHECKS_); + value_to_put_map.put(Settings.System.END_BUTTON_BEHAVIOR, + SEEMP_API_android_provider_Settings__put_END_BUTTON_BEHAVIOR_); + value_to_put_map.put(Settings.System.NEXT_ALARM_FORMATTED, + SEEMP_API_android_provider_Settings__put_NEXT_ALARM_FORMATTED_); + value_to_put_map.put(Settings.System.RADIO_CELL, + SEEMP_API_android_provider_Settings__put_RADIO_CELL_); + value_to_put_map.put(Settings.System.PARENTAL_CONTROL_ENABLED, + SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_ENABLED_); + value_to_put_map.put(Settings.System.BLUETOOTH_ON, + SEEMP_API_android_provider_Settings__put_BLUETOOTH_ON_); + value_to_put_map.put(Settings.System.WINDOW_ANIMATION_SCALE, + SEEMP_API_android_provider_Settings__put_WINDOW_ANIMATION_SCALE_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_); + value_to_put_map.put(Settings.System.BLUETOOTH_DISCOVERABILITY, + SEEMP_API_android_provider_Settings__put_BLUETOOTH_DISCOVERABILITY_); + value_to_put_map.put(Settings.System.WIFI_STATIC_DNS1, + SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS1_); + value_to_put_map.put(Settings.System.WIFI_STATIC_DNS2, + SEEMP_API_android_provider_Settings__put_WIFI_STATIC_DNS2_); + value_to_put_map.put(Settings.System.HAPTIC_FEEDBACK_ENABLED, + SEEMP_API_android_provider_Settings__put_HAPTIC_FEEDBACK_ENABLED_); + value_to_put_map.put(Settings.System.SHOW_WEB_SUGGESTIONS, + SEEMP_API_android_provider_Settings__put_SHOW_WEB_SUGGESTIONS_); + value_to_put_map.put(Settings.System.PARENTAL_CONTROL_REDIRECT_URL, + SEEMP_API_android_provider_Settings__put_PARENTAL_CONTROL_REDIRECT_URL_); + value_to_put_map.put(Settings.System.DATE_FORMAT, + SEEMP_API_android_provider_Settings__put_DATE_FORMAT_); + value_to_put_map.put(Settings.System.RADIO_NFC, + SEEMP_API_android_provider_Settings__put_RADIO_NFC_); + value_to_put_map.put(Settings.System.AIRPLANE_MODE_RADIOS, + SEEMP_API_android_provider_Settings__put_AIRPLANE_MODE_RADIOS_); + value_to_put_map.put(Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, + SEEMP_API_android_provider_Settings__put_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_); + value_to_put_map.put(Settings.System.TIME_12_24, + SEEMP_API_android_provider_Settings__put_TIME_12_24_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_); + value_to_put_map.put(Settings.System.VOLUME_BLUETOOTH_SCO, + SEEMP_API_android_provider_Settings__put_VOLUME_BLUETOOTH_SCO_); + value_to_put_map.put(Settings.System.USER_ROTATION, + SEEMP_API_android_provider_Settings__put_USER_ROTATION_); + value_to_put_map.put(Settings.System.WIFI_STATIC_GATEWAY, + SEEMP_API_android_provider_Settings__put_WIFI_STATIC_GATEWAY_); + value_to_put_map.put(Settings.System.STAY_ON_WHILE_PLUGGED_IN, + SEEMP_API_android_provider_Settings__put_STAY_ON_WHILE_PLUGGED_IN_); + value_to_put_map.put(Settings.System.SOUND_EFFECTS_ENABLED, + SEEMP_API_android_provider_Settings__put_SOUND_EFFECTS_ENABLED_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_PING_COUNT, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_PING_COUNT_); + value_to_put_map.put(Settings.System.DATA_ROAMING, + SEEMP_API_android_provider_Settings__put_DATA_ROAMING_); + value_to_put_map.put(Settings.System.SETTINGS_CLASSNAME, + SEEMP_API_android_provider_Settings__put_SETTINGS_CLASSNAME_); + value_to_put_map.put(Settings.System.TRANSITION_ANIMATION_SCALE, + SEEMP_API_android_provider_Settings__put_TRANSITION_ANIMATION_SCALE_); + value_to_put_map.put(Settings.System.WAIT_FOR_DEBUGGER, + SEEMP_API_android_provider_Settings__put_WAIT_FOR_DEBUGGER_); + value_to_put_map.put(Settings.System.INSTALL_NON_MARKET_APPS, + SEEMP_API_android_provider_Settings__put_INSTALL_NON_MARKET_APPS_); + value_to_put_map.put(Settings.System.ADB_ENABLED, + SEEMP_API_android_provider_Settings__put_ADB_ENABLED_); + value_to_put_map.put(Settings.System.WIFI_USE_STATIC_IP, + SEEMP_API_android_provider_Settings__put_WIFI_USE_STATIC_IP_); + value_to_put_map.put(Settings.System.DIM_SCREEN, + SEEMP_API_android_provider_Settings__put_DIM_SCREEN_); + value_to_put_map.put(Settings.System.VOLUME_ALARM, + SEEMP_API_android_provider_Settings__put_VOLUME_ALARM_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_ON, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ON_); + value_to_put_map.put(Settings.System.WIFI_STATIC_NETMASK, + SEEMP_API_android_provider_Settings__put_WIFI_STATIC_NETMASK_); + value_to_put_map.put(Settings.System.NETWORK_PREFERENCE, + SEEMP_API_android_provider_Settings__put_NETWORK_PREFERENCE_); + value_to_put_map.put(Settings.System.SHOW_PROCESSES, + SEEMP_API_android_provider_Settings__put_SHOW_PROCESSES_); + value_to_put_map.put(Settings.System.TEXT_AUTO_REPLACE, + SEEMP_API_android_provider_Settings__put_TEXT_AUTO_REPLACE_); + value_to_put_map.put(Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, + SEEMP_API_android_provider_Settings__put_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_); + value_to_put_map.put(Settings.System.APPEND_FOR_LAST_AUDIBLE, + SEEMP_API_android_provider_Settings__put_APPEND_FOR_LAST_AUDIBLE_); + value_to_put_map.put(Settings.System.SHOW_GTALK_SERVICE_STATUS, + SEEMP_API_android_provider_Settings__put_SHOW_GTALK_SERVICE_STATUS_); + value_to_put_map.put(Settings.System.SCREEN_BRIGHTNESS, + SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_); + value_to_put_map.put(Settings.System.USE_GOOGLE_MAIL, + SEEMP_API_android_provider_Settings__put_USE_GOOGLE_MAIL_); + value_to_put_map.put(Settings.System.RINGTONE, + SEEMP_API_android_provider_Settings__put_RINGTONE_); + value_to_put_map.put(Settings.System.LOGGING_ID, + SEEMP_API_android_provider_Settings__put_LOGGING_ID_); + value_to_put_map.put(Settings.System.MODE_RINGER, + SEEMP_API_android_provider_Settings__put_MODE_RINGER_); + value_to_put_map.put(Settings.System.MUTE_STREAMS_AFFECTED, + SEEMP_API_android_provider_Settings__put_MUTE_STREAMS_AFFECTED_); + value_to_put_map.put(Settings.System.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE, + SEEMP_API_android_provider_Settings__put_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE_); + value_to_put_map.put(Settings.System.TEXT_AUTO_PUNCTUATE, + SEEMP_API_android_provider_Settings__put_TEXT_AUTO_PUNCTUATE_); + value_to_put_map.put(Settings.System.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS, + SEEMP_API_android_provider_Settings__put_WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS_); + value_to_put_map.put(Settings.System.SCREEN_BRIGHTNESS_MODE, + SEEMP_API_android_provider_Settings__put_SCREEN_BRIGHTNESS_MODE_); + } + + public static int getSeempPutApiIdFromValue( String v ) + { + Integer result = value_to_put_map.get( v ); + if (result == null) + { + result = -1; + } + return result; + } +} diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java index ca54bef1e780..c83626008766 100644 --- a/core/java/android/view/AccessibilityIterators.java +++ b/core/java/android/view/AccessibilityIterators.java @@ -145,6 +145,9 @@ public int[] preceding(int offset) { @Override public void onConfigurationChanged(Configuration globalConfig) { final Locale locale = globalConfig.getLocales().get(0); + if (locale == null) { + return; + } if (!mLocale.equals(locale)) { mLocale = locale; onLocaleChanged(locale); diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 131fe1395585..910083daf08c 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -23,6 +23,7 @@ import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IShortcutService; import android.app.IAssistDataReceiver; +import android.content.Intent; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; @@ -277,6 +278,11 @@ interface IWindowManager */ oneway void statusBarVisibilityChanged(int visibility); + /** + * Send some ActionHandler commands to WindowManager. + */ + void sendCustomAction(in Intent intent); + /** * Called by System UI to notify of changes to the visibility of Recents. */ @@ -435,4 +441,14 @@ interface IWindowManager * @param displayId The id of the display. */ void dontOverrideDisplayInfo(int displayId); + + /** + * Call screen record from WindowManager. + */ + void screenRecordAction(int mode); + + boolean isGestureButtonEnabled(); + boolean isGestureButtonRegion(int i, int i2); + + boolean isKeyguardShowingAndNotOccluded(); } diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java index de195ae524c8..6223bc10222c 100644 --- a/core/java/android/view/InputChannel.java +++ b/core/java/android/view/InputChannel.java @@ -103,6 +103,13 @@ public String getName() { return name != null ? name : "uninitialized"; } + /** + * @hide + */ + public boolean isValid() { + return mPtr != 0; + } + /** * Disposes the input channel. * Explicitly releases the reference this object is holding on the input channel. diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 8405d9ea8c38..4ee57e0de2ac 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -273,6 +273,18 @@ public final class InputDevice implements Parcelable { */ public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE; + /** + * The input source is a touch device whose motions should be interpreted as gestures. + * + * For example, an upward swipe should be treated the same as a swipe of the touchscreen. + * The same should apply for left, right, down swipes. Complex gestures may also be input. + * + * @see #SOURCE_CLASS_NONE + * + * @hide + */ + public static final int SOURCE_GESTURE_SENSOR = 0x00800000 | SOURCE_CLASS_NONE; + /** * The input source is a joystick. * (It may also be a {@link #SOURCE_GAMEPAD}). @@ -1018,6 +1030,7 @@ public String toString() { appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad"); appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick"); appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad"); + appendSourceDescriptionIfApplicable(description, SOURCE_GESTURE_SENSOR, "gesture"); description.append(" )\n"); final int numAxes = mMotionRanges.size(); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index eec34cdc12cc..c848ecb6c18f 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -266,6 +266,14 @@ private static native void nativeSetOverrideScalingMode(long transactionObj, lon */ public static final int FX_SURFACE_DIM = 0x00020000; + /** + * Surface creation flag: Creates a container surface. + * This surface will have no buffers and will only be used + * as a container for other surfaces, or for its InputInfo. + * @hide + */ + public static final int FX_SURFACE_CONTAINER = 0x00080000; + /** * Mask used for FX values above. * @@ -522,13 +530,39 @@ public Builder setMetadata(int windowType, int ownerUid) { */ public Builder setColorLayer(boolean isColorLayer) { if (isColorLayer) { - mFlags |= FX_SURFACE_DIM; + setFlags(FX_SURFACE_DIM, FX_SURFACE_MASK); + } else { + setBufferLayer(); + } + return this; + } + + /** + * Indicates whether a 'ContainerLayer' is to be constructed. + * + * Container layers will not be rendered in any fashion and instead are used + * as a parent of renderable layers. + * + * @param isContainerLayer Whether to create a container layer. + * @hide + */ + public Builder setContainerLayer(boolean isContainerLayer) { + if (isContainerLayer) { + setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK); } else { - mFlags &= ~FX_SURFACE_DIM; + setBufferLayer(); } return this; } + /** + * Indicates whether a buffer layer is to be constructed. + * @hide + */ + public Builder setBufferLayer() { + return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK); + } + /** * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}. * @@ -539,6 +573,11 @@ public Builder setFlags(int flags) { mFlags = flags; return this; } + + private Builder setFlags(int flags, int mask) { + mFlags = (mFlags & ~mask) | flags; + return this; + } } /** diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 5952d782fa2a..18cbf9e923b8 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -166,6 +166,18 @@ public final class ThreadedRenderer { */ public static final String OVERDRAW_PROPERTY_SHOW = "show"; + /** + * Defines the rendering pipeline to be used by the ThreadedRenderer. + * + * Possible values: + * "skiagl", will use Skia's OpenGL renderer + * "skiavk", will use Skia's Vulkan renderer + * "opengl", will use OpenGL renderer + * + * @hide + */ + public static final String DEBUG_RENDERER_PROPERTY = "debug.hwui.renderer"; + /** * Turn on to debug non-rectangular clip operations. * diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 04e818247e39..ddef2e26eb92 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12494,6 +12494,7 @@ public boolean dispatchTouchEvent(MotionEvent event) { final int actionMasked = event.getActionMasked(); if (actionMasked == MotionEvent.ACTION_DOWN) { + android.util.SeempLog.record(3); // Defensive cleanup for new gesture stopNestedScroll(); } @@ -13150,6 +13151,7 @@ public boolean onKeyPreIme(int keyCode, KeyEvent event) { * @param event the KeyEvent object that defines the button action */ public boolean onKeyDown(int keyCode, KeyEvent event) { + android.util.SeempLog.record(4); if (KeyEvent.isConfirmKey(keyCode)) { if ((mViewFlags & ENABLED_MASK) == DISABLED) { return true; @@ -13202,6 +13204,7 @@ public boolean onKeyLongPress(int keyCode, KeyEvent event) { * @param event The KeyEvent object that defines the button action. */ public boolean onKeyUp(int keyCode, KeyEvent event) { + android.util.SeempLog.record(5); if (KeyEvent.isConfirmKey(keyCode)) { if ((mViewFlags & ENABLED_MASK) == DISABLED) { return true; @@ -13716,6 +13719,7 @@ protected boolean handleScrollBarDragging(MotionEvent event) { * @return True if the event was handled, false otherwise. */ public boolean onTouchEvent(MotionEvent event) { + android.util.SeempLog.record(3); final float x = event.getX(); final float y = event.getY(); final int viewFlags = mViewFlags; @@ -20295,23 +20299,27 @@ public void draw(Canvas canvas) { } saveCount = canvas.getSaveCount(); + int topSaveCount = -1; + int bottomSaveCount = -1; + int leftSaveCount = -1; + int rightSaveCount = -1; int solidColor = getSolidColor(); if (solidColor == 0) { if (drawTop) { - canvas.saveUnclippedLayer(left, top, right, top + length); + topSaveCount = canvas.saveUnclippedLayer(left, top, right, top + length); } if (drawBottom) { - canvas.saveUnclippedLayer(left, bottom - length, right, bottom); + bottomSaveCount = canvas.saveUnclippedLayer(left, bottom - length, right, bottom); } if (drawLeft) { - canvas.saveUnclippedLayer(left, top, left + length, bottom); + leftSaveCount = canvas.saveUnclippedLayer(left, top, left + length, bottom); } if (drawRight) { - canvas.saveUnclippedLayer(right - length, top, right, bottom); + rightSaveCount = canvas.saveUnclippedLayer(right - length, top, right, bottom); } } else { scrollabilityCache.setFadeColor(solidColor); @@ -20328,12 +20336,31 @@ public void draw(Canvas canvas) { final Matrix matrix = scrollabilityCache.matrix; final Shader fade = scrollabilityCache.shader; - if (drawTop) { - matrix.setScale(1, fadeHeight * topFadeStrength); + // must be restored in the reverse order that they were saved + if (drawRight) { + matrix.setScale(1, fadeHeight * rightFadeStrength); + matrix.postRotate(90); + matrix.postTranslate(right, top); + fade.setLocalMatrix(matrix); + p.setShader(fade); + if (solidColor == 0) { + canvas.restoreUnclippedLayer(rightSaveCount, p); + } else { + canvas.drawRect(right - length, top, right, bottom, p); + } + } + + if (drawLeft) { + matrix.setScale(1, fadeHeight * leftFadeStrength); + matrix.postRotate(-90); matrix.postTranslate(left, top); fade.setLocalMatrix(matrix); p.setShader(fade); - canvas.drawRect(left, top, right, top + length, p); + if (solidColor == 0) { + canvas.restoreUnclippedLayer(leftSaveCount, p); + } else { + canvas.drawRect(left, top, left + length, bottom, p); + } } if (drawBottom) { @@ -20342,25 +20369,23 @@ public void draw(Canvas canvas) { matrix.postTranslate(left, bottom); fade.setLocalMatrix(matrix); p.setShader(fade); - canvas.drawRect(left, bottom - length, right, bottom, p); + if (solidColor == 0) { + canvas.restoreUnclippedLayer(bottomSaveCount, p); + } else { + canvas.drawRect(left, bottom - length, right, bottom, p); + } } - if (drawLeft) { - matrix.setScale(1, fadeHeight * leftFadeStrength); - matrix.postRotate(-90); + if (drawTop) { + matrix.setScale(1, fadeHeight * topFadeStrength); matrix.postTranslate(left, top); fade.setLocalMatrix(matrix); p.setShader(fade); - canvas.drawRect(left, top, left + length, bottom, p); - } - - if (drawRight) { - matrix.setScale(1, fadeHeight * rightFadeStrength); - matrix.postRotate(90); - matrix.postTranslate(right, top); - fade.setLocalMatrix(matrix); - p.setShader(fade); - canvas.drawRect(right - length, top, right, bottom, p); + if (solidColor == 0) { + canvas.restoreUnclippedLayer(topSaveCount, p); + } else { + canvas.drawRect(left, top, right, top + length, p); + } } canvas.restoreToCount(saveCount); diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 7a9de45cbbf8..e2b6e117722e 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -62,7 +62,7 @@ public class ViewConfiguration { * Defines the default duration in milliseconds before a press turns into * a long press */ - private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500; + private static final int DEFAULT_LONG_PRESS_TIMEOUT = 250; /** * Defines the default duration in milliseconds between the first tap's up event and the second @@ -80,7 +80,7 @@ public class ViewConfiguration { * appropriate button to bring up the global actions dialog (power off, * lock screen, etc). */ - private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500; + private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 250; /** * Defines the duration in milliseconds a user needs to hold down the @@ -106,7 +106,7 @@ public class ViewConfiguration { * is a jump tap. If the user does not complete the jump tap within this interval, it is * considered to be a tap. */ - private static final int JUMP_TAP_TIMEOUT = 500; + private static final int JUMP_TAP_TIMEOUT = 250; /** * Defines the duration in milliseconds between the first tap's up event and @@ -140,12 +140,12 @@ public class ViewConfiguration { * Defines the duration in milliseconds we want to display zoom controls in response * to a user panning within an application. */ - private static final int ZOOM_CONTROLS_TIMEOUT = 3000; + private static final int ZOOM_CONTROLS_TIMEOUT = 1500; /** * Inset in dips to look for touchable content when the user touches the edge of the screen */ - private static final int EDGE_SLOP = 12; + private static final int EDGE_SLOP = 6; /** * Distance a touch can wander before we think the user is scrolling in dips. @@ -204,7 +204,7 @@ public class ViewConfiguration { /** * Maximum velocity to initiate a fling, as measured in dips per second */ - private static final int MAXIMUM_FLING_VELOCITY = 8000; + private static final int MAXIMUM_FLING_VELOCITY = 16000; /** * Delay before dispatching a recurring accessibility event in milliseconds. @@ -224,7 +224,7 @@ public class ViewConfiguration { /** * The coefficient of friction applied to flings/scrolls. */ - private static final float SCROLL_FRICTION = 0.015f; + private static final float SCROLL_FRICTION = 0.012f; /** * Max distance in dips to overscroll for edge effects diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a1c0967f0ab1..e2b065d8081c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -147,6 +147,19 @@ public final class ViewRootImpl implements ViewParent, private static final boolean DEBUG_INPUT_STAGES = false || LOCAL_LOGV; private static final boolean DEBUG_KEEP_SCREEN_ON = false || LOCAL_LOGV; + private static final float GESTURE_KEY_DISTANCE_THRESHOLD = 50.0f; + private static final long GESTURE_MOTION_QUEUE_DELAY = 200; + private static final int MSG_GESTURE_MOTION_DOWN = 5566; + private boolean mCheckForGestureButton = false; + private boolean mGestureButtonActive = false; + private int mGestureButtonZone = 0; + private boolean mQueueMotionConsumed = true; + private ArrayList mBackupEventList = new ArrayList(); + private float mRawX = 0.0f; + private float mRawY = 0.0f; + private int mScreenHeight = -1; + private int mScreenWidth = -1; + /** * Set to false if we do not want to use the multi threaded renderer even though * threaded renderer (aka hardware renderering) is used. Note that by disabling @@ -164,6 +177,9 @@ public final class ViewRootImpl implements ViewParent, public static final String PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX = "ro.emu.win_outset_bottom_px"; + private final int mSwipeStartThreshold = + SystemProperties.getInt("ro.bottom_gesture.swipe_start.threshold", 20); + /** * Maximum time we allow the user to roll the trackball enough to generate * a key event, before resetting the counters. @@ -544,6 +560,11 @@ public ViewRootImpl(Context context, Display display) { } loadSystemProperties(); + + DisplayMetrics dm = new DisplayMetrics(); + mAttachInfo.mDisplay.getRealMetrics(dm); + mScreenHeight = Math.max(dm.widthPixels, dm.heightPixels); + mScreenWidth = Math.min(dm.widthPixels, dm.heightPixels); } public static void addFirstDrawHandler(Runnable callback) { @@ -745,10 +766,7 @@ public void setView(View view, WindowManager.LayoutParams attrs, View panelParen // manager, to make sure we do the relayout before receiving // any other events from the system. requestLayout(); - if ((mWindowAttributes.inputFeatures - & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { - mInputChannel = new InputChannel(); - } + mInputChannel = new InputChannel(); mForceDecorViewVisibility = (mWindowAttributes.privateFlags & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0; try { @@ -838,7 +856,7 @@ public void setView(View view, WindowManager.LayoutParams attrs, View panelParen mInputQueueCallback = ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue(); } - if (mInputChannel != null) { + if (mInputChannel.isValid()) { if (mInputQueueCallback != null) { mInputQueue = new InputQueue(); mInputQueueCallback.onInputQueueCreated(mInputQueue); @@ -2817,8 +2835,8 @@ private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth int numValidRequests = validLayoutRequesters.size(); for (int i = 0; i < numValidRequests; ++i) { final View view = validLayoutRequesters.get(i); - Log.w("View", "requestLayout() improperly called by " + view + - " during layout: running second layout pass"); + // Log.w("View", "requestLayout() improperly called by " + view + + // " during layout: running second layout pass"); view.requestLayout(); } measureHierarchy(host, lp, mView.getContext().getResources(), @@ -2840,8 +2858,8 @@ public void run() { int numValidRequests = finalRequesters.size(); for (int i = 0; i < numValidRequests; ++i) { final View view = finalRequesters.get(i); - Log.w("View", "requestLayout() improperly called by " + view + - " during second layout pass: posting in next frame"); + // Log.w("View", "requestLayout() improperly called by " + view + + // " during second layout pass: posting in next frame"); view.requestLayout(); } } @@ -4060,6 +4078,8 @@ public String getMessageName(Message message) { return "MSG_POINTER_CAPTURE_CHANGED"; case MSG_DRAW_FINISHED: return "MSG_DRAW_FINISHED"; + case MSG_GESTURE_MOTION_DOWN: + return "MSG_GESTURE_MOTION_DOWN"; } return super.getMessageName(message); } @@ -4280,6 +4300,15 @@ public void handleMessage(Message msg) { case MSG_DRAW_FINISHED: { pendingDrawFinished(); } break; + case MSG_GESTURE_MOTION_DOWN: { + for (MotionEvent me : ViewRootImpl.this.mBackupEventList) { + try { + boolean ishandled = ViewRootImpl.this.mView.dispatchPointerEvent(me); + } catch (NullPointerException e) { + break; + } + } + } break; } } } @@ -5107,6 +5136,157 @@ private int processKeyEvent(QueuedInputEvent q) { private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; + int action; + int i; + int rotation; + boolean isLandscape; + float raw; + boolean hit; + + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); + boolean isGestureButtonEnabled = false; + try { + isGestureButtonEnabled = wm.isGestureButtonEnabled(); + } catch (RemoteException ex) { + isGestureButtonEnabled = false; + } + if (isGestureButtonEnabled) { + if (event.getPointerCount() == 1) { + action = event.getActionMasked(); + rotation = 0; + isLandscape = false; + if (action == 0 || mCheckForGestureButton || mGestureButtonActive) { + rotation = mAttachInfo.mDisplay.getRotation(); + isLandscape = rotation != 1 ? rotation == 3 : true; + } + + Message msg; + switch (action) { + case MotionEvent.ACTION_DOWN: + mCheckForGestureButton = false; + mGestureButtonActive = false; + mQueueMotionConsumed = true; + mBackupEventList.clear(); + if (isLandscape) { + raw = event.getRawX(); + } else { + raw = event.getRawY(); + } + if (rotation == 0 || rotation == 1) { + mGestureButtonZone = mScreenHeight - mSwipeStartThreshold; + hit = raw > ((float) mGestureButtonZone); + } else { + mGestureButtonZone = mSwipeStartThreshold; + hit = raw < ((float) mGestureButtonZone); + } + if (hit) { + mCheckForGestureButton = true; + mRawX = event.getRawX(); + mRawY = event.getRawY(); + mBackupEventList.add(MotionEvent.obtain(event)); + msg = Message.obtain(mHandler, + ViewRootImpl.MSG_GESTURE_MOTION_DOWN, mView); + mQueueMotionConsumed = false; + mHandler.sendMessageDelayed(msg, + ViewRootImpl.GESTURE_MOTION_QUEUE_DELAY); + return 1; + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + if (!mGestureButtonActive) { + if (mCheckForGestureButton) { + if (mHandler.hasMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN)) { + mHandler.removeMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN); + } + if (!mQueueMotionConsumed) { + for (MotionEvent me : mBackupEventList) { + try { + mView.dispatchPointerEvent(me); + } catch (NullPointerException e) { + break; + } + } + } + mQueueMotionConsumed = true; + mCheckForGestureButton = false; + mGestureButtonActive = false; + } + break; + } + mCheckForGestureButton = false; + mGestureButtonActive = false; + mQueueMotionConsumed = true; + return 1; + case MotionEvent.ACTION_MOVE: + if (mCheckForGestureButton) { + mBackupEventList.add(MotionEvent.obtain(event)); + boolean swipeTimeTooSlow = false; + boolean reachDistance = false; + if (event.getEventTime() - event.getDownTime() > 400) { + swipeTimeTooSlow = true; + } + float threshold = ViewRootImpl.GESTURE_KEY_DISTANCE_THRESHOLD; + if (rotation == 0 || rotation == 2) { + if (Math.abs(event.getRawY() - mRawY) > ((float) threshold)) { + reachDistance = true; + } + } else if (rotation == 1 || rotation == 3) { + if (Math.abs(event.getRawX() - mRawX) > ((float) threshold)) { + reachDistance = true; + } + } + if (reachDistance) { + mGestureButtonActive = true; + if (mHandler.hasMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN)) { + mHandler.removeMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN); + } + + mCheckForGestureButton = false; + mQueueMotionConsumed = true; + } else if (swipeTimeTooSlow) { + if (mHandler.hasMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN)) { + mHandler.removeMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN); + } + if (!mQueueMotionConsumed) { + for (MotionEvent me : mBackupEventList) { + try { + mView.dispatchPointerEvent(me); + } catch (NullPointerException e2) { + break; + } + } + } + mCheckForGestureButton = false; + mGestureButtonActive = false; + mQueueMotionConsumed = true; + } else if (mHandler.hasMessages( + ViewRootImpl.MSG_GESTURE_MOTION_DOWN)) { + mHandler.removeMessages(ViewRootImpl.MSG_GESTURE_MOTION_DOWN); + msg = Message.obtain(mHandler, + ViewRootImpl.MSG_GESTURE_MOTION_DOWN, mView); + mQueueMotionConsumed = false; + mHandler.sendMessageDelayed(msg, + (long) ViewRootImpl.GESTURE_MOTION_QUEUE_DELAY); + } + return 1; + } else if (mGestureButtonActive) { + return 1; + } + break; + } + } + } + + if (event.getPointerCount() == 3 && isSwipeToScreenshotGestureActive()) { + event.setAction(MotionEvent.ACTION_CANCEL); + } mAttachInfo.mUnbufferedDispatchRequested = false; mAttachInfo.mHandlingPointerEvent = true; @@ -5822,7 +6002,7 @@ final class SyntheticTouchNavigationHandler extends Handler { // probably not be set to anything less than about 4. // If fling accuracy is a problem then consider tuning the tick distance instead. private static final float MIN_FLING_VELOCITY_TICKS_PER_SECOND = 6f; - private static final float MAX_FLING_VELOCITY_TICKS_PER_SECOND = 20f; + private static final float MAX_FLING_VELOCITY_TICKS_PER_SECOND = 24f; // Fling velocity decay factor applied after each new key is emitted. // This parameter controls the deceleration and overall duration of the fling. @@ -7412,6 +7592,7 @@ public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { mUpcomingWindowFocus = hasFocus; mUpcomingInTouchMode = inTouchMode; } + Message msg = Message.obtain(); msg.what = MSG_WINDOW_FOCUS_CHANGED; mHandler.sendMessage(msg); @@ -8533,4 +8714,12 @@ boolean preViewDispatch(KeyEvent event) { return false; } } + + private boolean isSwipeToScreenshotGestureActive() { + try { + return ActivityManager.getService().isSwipeToScreenshotGestureActive(); + } catch (RemoteException e) { + return false; + } + } } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 93b3fc25509a..53ccc9d57850 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1085,6 +1085,11 @@ public void clearFlags(int flags) { setFlags(0, flags); } + /** @hide */ + public void clearPrivateFlags(int flags) { + setPrivateFlags(0, flags); + } + /** * Set the flags of the window, as per the * {@link WindowManager.LayoutParams WindowManager.LayoutParams} @@ -1112,6 +1117,10 @@ public void setFlags(int flags, int mask) { } private void setPrivateFlags(int flags, int mask) { + if ((flags & mask & WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY) != 0) { + mContext.enforceCallingOrSelfPermission("android.permission.PREVENT_POWER_KEY", + "No permission to prevent power key"); + } final WindowManager.LayoutParams attrs = getAttributes(); attrs.privateFlags = (attrs.privateFlags & ~mask) | (flags & mask); dispatchWindowAttributesChanged(attrs); diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 67e06e7b2c98..b4b99ac21584 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -395,6 +395,14 @@ public interface KeyboardShortcutsReceiver { */ final int TAKE_SCREENSHOT_SELECTED_REGION = 2; + /** + * Messages for starting a screen record session + * @hide + */ + final int SCREEN_RECORD_LOW_QUALITY = 0; + final int SCREEN_RECORD_MID_QUALITY = 1; + final int SCREEN_RECORD_HIGH_QUALITY = 2; + /** * @hide */ @@ -1410,6 +1418,12 @@ public static boolean isSystemAlertWindowType(int type) { */ public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000; + /** + * Window flag: Overrides default power key behavior + * @hide + */ + public static final int PRIVATE_FLAG_PREVENT_POWER_KEY = 0x20000000; + /** * Various behavioral options/flags. Default is none. * diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index a8722f101ef4..724859c688fe 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -89,12 +89,14 @@ public void setDefaultToken(IBinder token) { @Override public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { + android.util.SeempLog.record_vg_layout(383,params); applyDefaultToken(params); mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow); } @Override public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { + android.util.SeempLog.record_vg_layout(384,params); applyDefaultToken(params); mGlobal.updateViewLayout(view, params); } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 7e6af49838ce..f2a2ab450436 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1395,6 +1395,10 @@ boolean startInputInner(@InputMethodClient.StartInputReason final int startInput public void windowDismissed(IBinder appWindowToken) { checkFocus(); synchronized (mH) { + if (mCurRootView != null + && mCurRootView.getWindowToken() == appWindowToken) { + mCurRootView = null; + } if (mServedView != null && mServedView.getWindowToken() == appWindowToken) { finishInputLocked(); diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index 95fe963d7891..90bef2c7fd2f 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -317,7 +317,9 @@ public void onReachedMaxAppCacheSize(long requiredStorage, long quota, * origin. */ public void onGeolocationPermissionsShowPrompt(String origin, - GeolocationPermissions.Callback callback) {} + GeolocationPermissions.Callback callback) { + android.util.SeempLog.record(54); + } /** * Notify the host application that a request for Geolocation permissions, diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 6238e169e9e3..51416f9b5e0e 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -628,6 +628,7 @@ public abstract class AbsListView extends AdapterView implements Te Runnable mPositionScrollAfterLayout; private int mMinimumVelocity; private int mMaximumVelocity; + private int mDecacheThreshold; private float mVelocityScale = 1.0f; final boolean[] mIsScrap = new boolean[1]; @@ -881,6 +882,7 @@ private void initAbsListView() { mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); + mDecacheThreshold = mMaximumVelocity / 2; mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); @@ -4605,7 +4607,7 @@ public void run() { // Keep the fling alive a little longer postDelayed(this, FLYWHEEL_TIMEOUT); } else { - endFling(); + endFling(false); // Don't disable the scrolling cache right after it was enabled mTouchMode = TOUCH_MODE_SCROLL; reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } @@ -4616,9 +4618,15 @@ public void run() { FlingRunnable() { mScroller = new OverScroller(getContext()); + mScroller.setFriction(0.006f); } void start(int initialVelocity) { + if (Math.abs(initialVelocity) > mDecacheThreshold) { + // For long flings, scrolling cache causes stutter, so don't use it + clearScrollingCache(); + } + int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0; mLastFlingY = initialY; mScroller.setInterpolator(null); @@ -4696,6 +4704,10 @@ void startScroll(int distance, int duration, boolean linear, } void endFling() { + endFling(true); + } + + void endFling(boolean clearCache) { mTouchMode = TOUCH_MODE_REST; removeCallbacks(this); @@ -4704,7 +4716,8 @@ void endFling() { if (!mSuppressIdleStateChangeCall) { reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } - clearScrollingCache(); + if (clearCache) + clearScrollingCache(); mScroller.abortAnimation(); if (mFlingStrictSpan != null) { diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 61a58733479f..9ab1d3f6d098 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -81,6 +81,7 @@ public abstract class AbsSeekBar extends ProgressBar { private int mScaledTouchSlop; private float mTouchDownX; private boolean mIsDragging; + private float mTouchThumbOffset = 0.0f; public AbsSeekBar(Context context) { super(context); @@ -767,6 +768,14 @@ public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: + if (mThumb != null) { + final int availableWidth = getWidth() - mPaddingLeft - mPaddingRight; + mTouchThumbOffset = (getProgress() - getMin()) / (float) (getMax() + - getMin()) - (event.getX() - mPaddingLeft) / availableWidth; + if (Math.abs(mTouchThumbOffset * availableWidth) > getThumbOffset()) { + mTouchThumbOffset = 0; + } + } if (isInScrollingContainer()) { mTouchDownX = event.getX(); } else { @@ -848,7 +857,8 @@ private void trackTouchEvent(MotionEvent event) { } else if (x < mPaddingLeft) { scale = 1.0f; } else { - scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth; + scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth + + mTouchThumbOffset; progress = mTouchProgressOffset; } } else { @@ -857,7 +867,7 @@ private void trackTouchEvent(MotionEvent event) { } else if (x > width - mPaddingRight) { scale = 1.0f; } else { - scale = (x - mPaddingLeft) / (float) availableWidth; + scale = (x - mPaddingLeft) / (float) availableWidth + mTouchThumbOffset; progress = mTouchProgressOffset; } } @@ -866,7 +876,15 @@ private void trackTouchEvent(MotionEvent event) { progress += scale * range + getMin(); setHotspot(x, y); - setProgressInternal(Math.round(progress), true, false); + setProgressInternal(updateTouchProgress(getProgress(), + Math.round(progress)), true, false); + } + + /** + * @hide + */ + protected int updateTouchProgress(int lastProgress, int newProgress) { + return newProgress; } /** diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 198bf2722d99..29709142a49a 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -359,7 +359,7 @@ public void setStyle(@StyleRes int resId) { mTextAppearance = ta.getResourceId(index, 0); break; case R.styleable.FastScroll_textColor: - mTextColor = ta.getColorStateList(index); + mTextColor = ColorStateList.valueOf(context.getResources().getColor(R.color.fastscroller_text_color)); break; case R.styleable.FastScroll_textSize: mTextSize = ta.getDimensionPixelSize(index, 0); diff --git a/core/java/android/widget/ImageSwitcher.java b/core/java/android/widget/ImageSwitcher.java index 112fcc313366..d8f9953f37f7 100644 --- a/core/java/android/widget/ImageSwitcher.java +++ b/core/java/android/widget/ImageSwitcher.java @@ -94,10 +94,27 @@ public void setImageURI(Uri uri) public void setImageDrawable(Drawable drawable) { ImageView image = (ImageView)this.getNextView(); + image.setImageTintList(null); image.setImageDrawable(drawable); showNext(); } + /** + * @hide + */ + public void setImageDrawableTint(Drawable drawable, int tint, boolean isGrayscale) + { + ImageView image = (ImageView)this.getNextView(); + if (isGrayscale) { + drawable.setTint(tint); + image.setImageDrawable(drawable); + } else { + image.setImageDrawable(drawable); + image.setImageTintList(null); + } + showNext(); + } + @Override public CharSequence getAccessibilityClassName() { return ImageSwitcher.class.getName(); diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 97d32f1266af..661c7d378135 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -84,7 +84,7 @@ public class ScrollView extends FrameLayout { private long mLastScroll; private final Rect mTempRect = new Rect(); - private OverScroller mScroller; + private static OverScroller mScroller; private EdgeEffect mEdgeGlowTop; private EdgeEffect mEdgeGlowBottom; @@ -116,7 +116,7 @@ public class ScrollView extends FrameLayout { /** * Determines speed during touch scrolling */ - private VelocityTracker mVelocityTracker; + private static VelocityTracker mVelocityTracker; /** * When set to true, the scroll view measure its child to make it fill the currently @@ -189,7 +189,6 @@ public ScrollView(Context context, AttributeSet attrs, int defStyleAttr, int def attrs, com.android.internal.R.styleable.ScrollView, defStyleAttr, defStyleRes); setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false)); - a.recycle(); if (context.getResources().getConfiguration().uiMode == Configuration.UI_MODE_TYPE_WATCH) { @@ -243,6 +242,7 @@ public int getMaxScrollAmount() { private void initScrollView() { mScroller = new OverScroller(getContext()); + mScroller.setFriction(0.006f); setFocusable(true); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setWillNotDraw(false); @@ -465,7 +465,7 @@ private void initVelocityTrackerIfNotExists() { } } - private void recycleVelocityTracker() { + private static void recycleVelocityTracker() { if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; @@ -692,7 +692,9 @@ public boolean onTouchEvent(MotionEvent ev) { if (overScrollBy(0, deltaY, 0, mScrollY, 0, range, 0, mOverscrollDistance, true) && !hasNestedScrollingParent()) { // Break our velocity if we hit a scroll barrier. - mVelocityTracker.clear(); + if (mVelocityTracker != null) { + mVelocityTracker.clear(); + } } final int scrolledDeltaY = mScrollY - oldY; diff --git a/core/java/android/widget/TextSwitcher.java b/core/java/android/widget/TextSwitcher.java index ecd9a8cfb3d1..e8e3a5722637 100644 --- a/core/java/android/widget/TextSwitcher.java +++ b/core/java/android/widget/TextSwitcher.java @@ -93,4 +93,14 @@ public void setCurrentText(CharSequence text) { public CharSequence getAccessibilityClassName() { return TextSwitcher.class.getName(); } + + /** + * Sets the color of the text view that is currently showing. + * + * @param color the text color to display + * @hide + */ + public void setTextColor(int color) { + ((TextView)getCurrentView()).setTextColor(color); + } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 1e4cdc593616..5f1073088d02 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -16,6 +16,7 @@ package android.widget; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; @@ -31,11 +32,13 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; +import android.annotation.RequiresPermission; import android.annotation.Size; import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.XmlRes; import android.app.Activity; +import android.app.ActivityManager; import android.app.PendingIntent; import android.app.assist.AssistStructure; import android.content.ClipData; @@ -72,6 +75,7 @@ import android.os.Parcelable; import android.os.ParcelableParcel; import android.os.SystemClock; +import android.os.UserHandle; import android.provider.Settings; import android.text.BoringLayout; import android.text.DynamicLayout; @@ -723,6 +727,19 @@ private void applyErrorDrawableIfNeeded(int layoutDirection) { private InputFilter[] mFilters = NO_FILTERS; + /** + * To keep the information to indicate if there is necessary to restrict the power of + * INTERACT_ACROSS_USERS_FULL. + *

+ * SystemUI always run as user 0 to process all of direct reply. SystemUI has the poer of + * INTERACT_ACROSS_USERS_FULL. However, all of the notifications not only belong to user 0 but + * also to the other users in multiple user environment. + *

+ * + * @see #setRestrictedAcrossUser(boolean) + */ + private boolean mIsRestrictedAcrossUser; + private volatile Locale mCurrentSpellCheckerLocaleCache; // It is possible to have a selection even when mEditor is null (programmatically set, like when @@ -10439,6 +10456,24 @@ private Locale getTextServicesLocale(boolean allowNullLocale) { : mCurrentSpellCheckerLocaleCache; } + /** + * To notify the TextView to restricted the power of the app granted INTERACT_ACROSS_USERS_FULL + * permission. + *

+ * Most of applications should not granted the INTERACT_ACROSS_USERS_FULL permssion. + * SystemUI is the special one that run in user 0 process to handle multiple user notification. + * Unforunately, the power of INTERACT_ACROSS_USERS_FULL should be limited or restricted for + * preventing from information leak.

+ *

This function call is called for SystemUI Keyguard and Notification.

+ * + * @param isRestricted is true if the power of INTERACT_ACROSS_USERS_FULL should be limited. + * @hide + */ + @RequiresPermission(INTERACT_ACROSS_USERS_FULL) + public final void setRestrictedAcrossUser(boolean isRestricted) { + mIsRestrictedAcrossUser = isRestricted; + } + /** * This is a temporary method. Future versions may support multi-locale text. * Caveat: This method may not return the latest text services locale, but this should be @@ -11647,6 +11682,12 @@ boolean canRedo() { } boolean canCut() { + if (mIsRestrictedAcrossUser + && UserHandle.myUserId() != ActivityManager.getCurrentUser()) { + // When it's restricted, and the curren user is not the process user. It can't cut + // because it may cut the text of the user 10 into the clipboard of user 0. + return false; + } if (hasPasswordTransformationMethod()) { return false; } @@ -11660,6 +11701,12 @@ boolean canCut() { } boolean canCopy() { + if (mIsRestrictedAcrossUser + && UserHandle.myUserId() != ActivityManager.getCurrentUser()) { + // When it's restricted, and the curren user is not the process user. It can't copy + // because it may copy the text of the user 10 to the clipboard of user 0. + return false; + } if (hasPasswordTransformationMethod()) { return false; } @@ -11689,6 +11736,12 @@ boolean isDeviceProvisioned() { } boolean canPaste() { + if (mIsRestrictedAcrossUser + && UserHandle.myUserId() != ActivityManager.getCurrentUser()) { + // When it's restricted, and the curren user is not the process user. It can't paste + // because it may copy the text from the user 0 clipboard in current user is 10. + return false; + } return (mText instanceof Editable && mEditor != null && mEditor.mKeyListener != null && getSelectionStart() >= 0 diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java index 77670b35a1ea..6c039d873493 100644 --- a/core/java/android/widget/TimePickerClockDelegate.java +++ b/core/java/android/widget/TimePickerClockDelegate.java @@ -454,6 +454,7 @@ private void setAmPmStart(boolean isAmPmAtStart) { (RelativeLayout.LayoutParams) mAmPmLayout.getLayoutParams(); if (params.getRule(RelativeLayout.RIGHT_OF) != 0 || params.getRule(RelativeLayout.LEFT_OF) != 0) { + final int margin = (int) (mContext.getResources().getDisplayMetrics().density * 8); // Horizontal mode, with AM/PM appearing to left/right of hours and minutes. final boolean isAmPmAtLeft; if (TextUtils.getLayoutDirectionFromLocale(mLocale) == View.LAYOUT_DIRECTION_LTR) { @@ -461,10 +462,6 @@ private void setAmPmStart(boolean isAmPmAtStart) { } else { isAmPmAtLeft = !isAmPmAtStart; } - if (mIsAmPmAtLeft == isAmPmAtLeft) { - // AM/PM is already at the correct location. No change needed. - return; - } if (isAmPmAtLeft) { params.removeRule(RelativeLayout.RIGHT_OF); @@ -473,6 +470,14 @@ private void setAmPmStart(boolean isAmPmAtStart) { params.removeRule(RelativeLayout.LEFT_OF); params.addRule(RelativeLayout.RIGHT_OF, mMinuteView.getId()); } + + if (isAmPmAtStart) { + params.setMarginStart(0); + params.setMarginEnd(margin); + } else { + params.setMarginStart(margin); + params.setMarginEnd(0); + } mIsAmPmAtLeft = isAmPmAtLeft; } else if (params.getRule(RelativeLayout.BELOW) != 0 || params.getRule(RelativeLayout.ABOVE) != 0) { diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index d74a60e483e5..269d4df1efef 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -23,15 +23,18 @@ import android.app.INotificationManager; import android.app.ITransientNotification; import android.content.Context; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; +import android.provider.Settings; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; @@ -466,6 +469,20 @@ public void handleShow(IBinder windowToken) { if (context == null) { context = mView.getContext(); } + + ImageView appIcon = (ImageView) mView.findViewById(android.R.id.icon); + if ((Settings.System.getInt(context.getContentResolver(), Settings.System.TOAST_ICON, 0) == 1)) { + if (appIcon != null) { + PackageManager pm = context.getPackageManager(); + Drawable icon = null; + try { + icon = pm.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + // nothing to do + } + appIcon.setImageDrawable(icon); + } + } mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); // We can resolve the Gravity here by using the Locale for getting // the layout direction diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index c31f17af67af..7e6c027b3d91 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -101,7 +101,7 @@ public class ChooserActivity extends ResolverActivity { private static final boolean DEBUG = false; - private static final int QUERY_TARGET_SERVICE_LIMIT = 5; + private static final int QUERY_TARGET_SERVICE_LIMIT = 3; private static final int WATCHDOG_TIMEOUT_MILLIS = 2000; private Bundle mReplacementExtras; @@ -1329,7 +1329,7 @@ void bindViewHolder(int rowPosition, RowViewHolder holder) { if (startType == ChooserListAdapter.TARGET_SERVICE) { holder.row.setBackgroundColor( - getColor(R.color.chooser_service_row_background_color)); + getColor(R.color.chooser_service_row_background_color_exposed)); int nextStartType = mChooserListAdapter.getPositionTargetType( getFirstRowPosition(rowPosition + 1)); int serviceSpacing = holder.row.getContext().getResources() diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 0ed972477123..c2a1a3432133 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -56,4 +56,11 @@ interface IAppOpsService { boolean isOperationActive(int code, int uid, String packageName); void startWatchingModeWithFlags(int op, String packageName, int flags, IAppOpsCallback callback); + + // Privacy guard methods + boolean getPrivacyGuardSettingForPackage(int uid, String packageName); + void setPrivacyGuardSettingForPackage(int uid, String packageName, boolean state); + + // AppOps accounting + void resetCounters(); } diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 514ff76372a9..ce03e4e865e5 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -154,4 +154,7 @@ interface IBatteryStats { oneway void noteBluetoothControllerActivity(in BluetoothActivityEnergyInfo info); oneway void noteModemControllerActivity(in ModemActivityInfo info); oneway void noteWifiControllerActivity(in WifiActivityEnergyInfo info); + + /** @hide **/ + void resetStatistics(); } diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java index c8c2fcf60d1f..ed68ef7b36c5 100644 --- a/core/java/com/android/internal/app/LocalePicker.java +++ b/core/java/com/android/internal/app/LocalePicker.java @@ -166,7 +166,7 @@ public static ArrayAdapter constructAdapter(Context context) { public static ArrayAdapter constructAdapter(Context context, final int layoutId, final int fieldId) { boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(), - Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0; final List localeInfos = getAllAssetLocales(context, isInDeveloperMode); final LayoutInflater inflater = diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index ceb06f511108..f7adc7d0a28f 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -252,7 +252,7 @@ protected void onCreate(Bundle savedInstanceState, Intent intent, protected void onCreate(Bundle savedInstanceState, Intent intent, CharSequence title, int defaultTitleRes, Intent[] initialIntents, List rList, boolean supportsAlwaysUseOption) { - setTheme(R.style.Theme_DeviceDefault_Resolver); + setTheme(R.style.Theme_DeviceDefault_Resolver_Exposed); super.onCreate(savedInstanceState); // Determine whether we should show that intent is forwarded @@ -780,25 +780,6 @@ protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) { if (TextUtils.isEmpty(packageName)) { pm.setDefaultBrowserPackageNameAsUser(ri.activityInfo.packageName, userId); } - } else { - // Update Domain Verification status - ComponentName cn = intent.getComponent(); - String packageName = cn.getPackageName(); - String dataScheme = (data != null) ? data.getScheme() : null; - - boolean isHttpOrHttps = (dataScheme != null) && - (dataScheme.equals(IntentFilter.SCHEME_HTTP) || - dataScheme.equals(IntentFilter.SCHEME_HTTPS)); - - boolean isViewAction = (action != null) && action.equals(Intent.ACTION_VIEW); - boolean hasCategoryBrowsable = (categories != null) && - categories.contains(Intent.CATEGORY_BROWSABLE); - - if (isHttpOrHttps && isViewAction && hasCategoryBrowsable) { - pm.updateIntentVerificationStatusAsUser(packageName, - PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, - userId); - } } } else { try { diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 25ea397c2e98..fc55a1445083 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -245,6 +245,7 @@ public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener liste public static class GradientColors { private int mMainColor; private int mSecondaryColor; + private int[] mColorPalette; private boolean mSupportsDarkText; public void setMainColor(int mainColor) { @@ -255,6 +256,10 @@ public void setSecondaryColor(int secondaryColor) { mSecondaryColor = secondaryColor; } + public void setColorPalette(int[] colorPalette) { + mColorPalette = colorPalette; + } + public void setSupportsDarkText(boolean supportsDarkText) { mSupportsDarkText = supportsDarkText; } @@ -262,6 +267,7 @@ public void setSupportsDarkText(boolean supportsDarkText) { public void set(GradientColors other) { mMainColor = other.mMainColor; mSecondaryColor = other.mSecondaryColor; + mColorPalette = other.mColorPalette; mSupportsDarkText = other.mSupportsDarkText; } @@ -273,6 +279,10 @@ public int getSecondaryColor() { return mSecondaryColor; } + public int[] getColorPalette() { + return mColorPalette; + } + public boolean supportsDarkText() { return mSupportsDarkText; } diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java index 7b25a0691c40..083c63a6c5d9 100644 --- a/core/java/com/android/internal/colorextraction/types/Tonal.java +++ b/core/java/com/android/internal/colorextraction/types/Tonal.java @@ -175,6 +175,7 @@ private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY); float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f); float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f); + int[] colorPalette = getColorPalette(h, s, l); if (DEBUG) { StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex + @@ -211,6 +212,7 @@ private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors, // Normal colors: outColorsNormal.setMainColor(mainColor); outColorsNormal.setSecondaryColor(mainColor); + outColorsNormal.setColorPalette(colorPalette); // Dark colors: // Stops at 4th color, only lighter if dark text is supported @@ -224,6 +226,7 @@ private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors, mainColor = getColorInt(primaryIndex, h, s, l); outColorsDark.setMainColor(mainColor); outColorsDark.setSecondaryColor(mainColor); + outColorsDark.setColorPalette(colorPalette); // Extra Dark: // Stay close to dark colors until dark text is supported @@ -237,6 +240,7 @@ private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors, mainColor = getColorInt(primaryIndex, h, s, l); outColorsExtraDark.setMainColor(mainColor); outColorsExtraDark.setSecondaryColor(mainColor); + outColorsExtraDark.setColorPalette(colorPalette); outColorsNormal.setSupportsDarkText(supportsDarkText); outColorsDark.setSupportsDarkText(supportsDarkText); @@ -250,6 +254,18 @@ private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors, return true; } + private int[] getColorPalette(float[] h, float[] s, float[] l) { + int[] palette = new int[h.length]; + for (int i = 0; i < palette.length; i++) { + palette[i] = getColorInt(i, h, s, l); + } + return palette; + } + + private int[] getColorPalette(TonalPalette tonalPalette) { + return getColorPalette(tonalPalette.h, tonalPalette.s, tonalPalette.l); + } + private void applyFallback(@Nullable WallpaperColors inWallpaperColors, GradientColors outColorsNormal, GradientColors outColorsDark, GradientColors outColorsExtraDark) { @@ -264,16 +280,19 @@ private void applyFallback(@Nullable WallpaperColors inWallpaperColors, * @param inWallpaperColors Colors to read. * @param outGradientColors Destination. */ - public static void applyFallback(@Nullable WallpaperColors inWallpaperColors, + public void applyFallback(@Nullable WallpaperColors inWallpaperColors, @NonNull GradientColors outGradientColors) { boolean light = inWallpaperColors != null && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0; final int color = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK; + ColorUtils.colorToHSL(color, mTmpHSL); + outGradientColors.setMainColor(color); outGradientColors.setSecondaryColor(color); outGradientColors.setSupportsDarkText(light); + outGradientColors.setColorPalette(getColorPalette(findTonalPalette(mTmpHSL[0], mTmpHSL[1]))); } private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) { diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index b591163e8728..7f4f65b814d6 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -93,6 +93,14 @@ protected void onDocIdChanged(String docId) { // Default is no-op } + /** + * Callback indicating that the given document has been deleted or moved. This gives + * the provider a hook to revoke the uri permissions. + */ + protected void onDocIdDeleted(String docId) { + // Default is no-op + } + @Override public boolean onCreate() { throw new UnsupportedOperationException( @@ -236,6 +244,7 @@ public String renameDocument(String docId, String displayName) throws FileNotFou displayName = FileUtils.buildValidFatFilename(displayName); final File before = getFileForDocId(docId); + final File beforeVisibleFile = getFileForDocId(docId, true); final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName); if (!before.renameTo(after)) { throw new IllegalStateException("Failed to rename to " + after); @@ -243,9 +252,10 @@ public String renameDocument(String docId, String displayName) throws FileNotFou final String afterDocId = getDocIdForFile(after); onDocIdChanged(docId); + onDocIdDeleted(docId); onDocIdChanged(afterDocId); - final File beforeVisibleFile = getFileForDocId(docId, true); + final File afterVisibleFile = getFileForDocId(afterDocId, true); moveInMediaStore(beforeVisibleFile, afterVisibleFile); @@ -274,6 +284,7 @@ public String moveDocument(String sourceDocumentId, String sourceParentDocumentI final String docId = getDocIdForFile(after); onDocIdChanged(sourceDocumentId); + onDocIdDeleted(sourceDocumentId); onDocIdChanged(docId); moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true)); @@ -325,6 +336,7 @@ public void deleteDocument(String docId) throws FileNotFoundException { } onDocIdChanged(docId); + onDocIdDeleted(docId); removeFromMediaStore(visibleFile, isDirectory); } diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java index 07bb4533c4e0..a8f763ef7fa9 100644 --- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java +++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java @@ -39,6 +39,8 @@ public boolean enabled(int user) { || pulseOnPickupEnabled(user) || pulseOnDoubleTapEnabled(user) || pulseOnLongPressEnabled(user) + || pulseOnCustomDozeEventEnabled(user) + || pulseOnMedia(user) || alwaysOnEnabled(user); } @@ -55,6 +57,22 @@ public boolean pulseOnNotificationAvailable() { return ambientDisplayAvailable(); } + private boolean pulseOnCustomDozeEventEnabled(int user) { + return (Settings.System.getInt(mContext.getContentResolver(), Settings.System.CUSTOM_AMBIENT_POCKETMODE_GESTURE, 0) != 0 + || Settings.System.getInt(mContext.getContentResolver(), Settings.System.CUSTOM_AMBIENT_HANDWAVE_GESTURE, 0) != 0) + && pulseOnNotificationAvailable(); + } + + public boolean pulseOnMedia(int user) { + boolean enabled = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.FORCE_AMBIENT_FOR_MEDIA, 1, user) != 0; + return enabled && ambientDisplayAvailable(); + } + + public boolean canForceDozeNotifications() { + return mContext.getResources().getBoolean(R.bool.config_canForceDozeNotifications); + } + public boolean pulseOnPickupEnabled(int user) { boolean settingEnabled = boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user); return (settingEnabled || alwaysOnEnabled(user)) && pulseOnPickupAvailable(); @@ -103,8 +121,7 @@ private boolean pulseOnLongPressAvailable() { } public boolean alwaysOnEnabled(int user) { - return boolSetting(Settings.Secure.DOZE_ALWAYS_ON, user, mAlwaysOnByDefault ? 1 : 0) - && alwaysOnAvailable() && !accessibilityInversionEnabled(user); + return alwaysOnEnabledSetting(user) || alwaysOnChargingEnabled(user); } public boolean alwaysOnAvailable() { @@ -148,4 +165,22 @@ private boolean boolSettingDefaultOff(String name, int user) { private boolean boolSetting(String name, int user, int def) { return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0; } + + private boolean boolSettingSystem(String name, int user, int def) { + return Settings.System.getIntForUser(mContext.getContentResolver(), name, def, user) != 0; + } + + public boolean alwaysOnEnabledSetting(int user) { + boolean alwaysOnEnabled = boolSetting(Settings.Secure.DOZE_ALWAYS_ON, user, mAlwaysOnByDefault ? 1 : 0); + return alwaysOnEnabled && alwaysOnAvailable() && !accessibilityInversionEnabled(user); + } + + public boolean alwaysOnChargingEnabled(int user) { + final boolean dozeOnChargeEnabled = boolSettingSystem(Settings.System.DOZE_ON_CHARGE, user, 0); + if (dozeOnChargeEnabled) { + final boolean dozeOnChargeEnabledNow = boolSettingSystem(Settings.System.DOZE_ON_CHARGE_NOW, user, 0); + return dozeOnChargeEnabledNow && alwaysOnAvailable() && !accessibilityInversionEnabled(user); + } + return false; + } } diff --git a/core/java/com/android/internal/icons/FixedScaleDrawable.java b/core/java/com/android/internal/icons/FixedScaleDrawable.java new file mode 100644 index 000000000000..919dcd50efd5 --- /dev/null +++ b/core/java/com/android/internal/icons/FixedScaleDrawable.java @@ -0,0 +1,55 @@ +package com.android.internal.icons; + +import android.annotation.TargetApi; +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.DrawableWrapper; +import android.os.Build; +import android.util.AttributeSet; + +import org.xmlpull.v1.XmlPullParser; + +/** + * Extension of {@link DrawableWrapper} which scales the child drawables by a fixed amount. + */ +public class FixedScaleDrawable extends DrawableWrapper { + + // TODO b/33553066 use the constant defined in MaskableIconDrawable + private static final float LEGACY_ICON_SCALE = .7f * .6667f; + private float mScaleX, mScaleY; + + public FixedScaleDrawable() { + super(new ColorDrawable()); + mScaleX = LEGACY_ICON_SCALE; + mScaleY = LEGACY_ICON_SCALE; + } + + @Override + public void draw(Canvas canvas) { + int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); + canvas.scale(mScaleX, mScaleY, + getBounds().exactCenterX(), getBounds().exactCenterY()); + super.draw(canvas); + canvas.restoreToCount(saveCount); + } + + @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) { } + + @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) { } + + public void setScale(float scale) { + float h = getIntrinsicHeight(); + float w = getIntrinsicWidth(); + mScaleX = scale * LEGACY_ICON_SCALE; + mScaleY = scale * LEGACY_ICON_SCALE; + if (h > w && w > 0) { + mScaleX *= w / h; + } else if (w > h && h > 0) { + mScaleY *= h / w; + } + } +} diff --git a/core/java/com/android/internal/icons/IconNormalizer.java b/core/java/com/android/internal/icons/IconNormalizer.java new file mode 100644 index 000000000000..824dd699db5a --- /dev/null +++ b/core/java/com/android/internal/icons/IconNormalizer.java @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.icons; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.Drawable; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.util.Log; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.ByteBuffer; +import java.util.Random; + +public class IconNormalizer { + + private static final String TAG = "IconNormalizer"; + // Ratio of icon visible area to full icon size for a square shaped icon + private static final float MAX_SQUARE_AREA_FACTOR = 375.0f / 576; + // Ratio of icon visible area to full icon size for a circular shaped icon + private static final float MAX_CIRCLE_AREA_FACTOR = 380.0f / 576; + + private static final float CIRCLE_AREA_BY_RECT = (float) Math.PI / 4; + + // Slope used to calculate icon visible area to full icon size for any generic shaped icon. + private static final float LINEAR_SCALE_SLOPE = + (MAX_CIRCLE_AREA_FACTOR - MAX_SQUARE_AREA_FACTOR) / (1 - CIRCLE_AREA_BY_RECT); + + private static final int MIN_VISIBLE_ALPHA = 40; + + // Shape detection related constants + private static final float BOUND_RATIO_MARGIN = .05f; + private static final float PIXEL_DIFF_PERCENTAGE_THRESHOLD = 0.005f; + private static final float SCALE_NOT_INITIALIZED = 0; + + private static final Object LOCK = new Object(); + private static IconNormalizer sIconNormalizer; + + private final int mMaxSize; + private final Bitmap mBitmap; + private final Bitmap mBitmapARGB; + private final Canvas mCanvas; + private final Paint mPaintMaskShape; + private final Paint mPaintMaskShapeOutline; + private final byte[] mPixels; + private final int[] mPixelsARGB; + + private final Rect mAdaptiveIconBounds; + private float mAdaptiveIconScale; + + // for each y, stores the position of the leftmost x and the rightmost x + private final float[] mLeftBorder; + private final float[] mRightBorder; + private final Rect mBounds; + private final Matrix mMatrix; + + private final Paint mPaintIcon; + private final Canvas mCanvasARGB; + + private final File mDir; + private int mFileId; + private final Random mRandom; + + private float mScaleFactor; + private int mIconSizeId; + + public IconNormalizer(Context context, int iconSizeId, float scaleFactor) { + mScaleFactor = scaleFactor; + mIconSizeId = iconSizeId; + // Use twice the icon size as maximum size to avoid scaling down twice. + mMaxSize = ((int) (context.getResources() + .getDimensionPixelSize(iconSizeId) * scaleFactor)) * 2; + mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8); + mCanvas = new Canvas(mBitmap); + mPixels = new byte[mMaxSize * mMaxSize]; + mPixelsARGB = new int[mMaxSize * mMaxSize]; + mLeftBorder = new float[mMaxSize]; + mRightBorder = new float[mMaxSize]; + mBounds = new Rect(); + mAdaptiveIconBounds = new Rect(); + + // Needed for isShape() method + mBitmapARGB = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ARGB_8888); + mCanvasARGB = new Canvas(mBitmapARGB); + + mPaintIcon = new Paint(); + mPaintIcon.setColor(Color.WHITE); + + mPaintMaskShape = new Paint(); + mPaintMaskShape.setColor(Color.RED); + mPaintMaskShape.setStyle(Paint.Style.FILL); + mPaintMaskShape.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR)); + + mPaintMaskShapeOutline = new Paint(); + mPaintMaskShapeOutline.setStrokeWidth(2 * context.getResources().getDisplayMetrics().density); + mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE); + mPaintMaskShapeOutline.setColor(Color.BLACK); + mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); + + mMatrix = new Matrix(); + mAdaptiveIconScale = SCALE_NOT_INITIALIZED; + + mDir = context.getExternalFilesDir(null); + mRandom = new Random(); + } + + public float getScaleFactor() { + return mScaleFactor; + } + + public int getIconSizeId() { + return mIconSizeId; + } + + /** + * Returns if the shape of the icon is same as the path. + * For this method to work, the shape path bounds should be in [0,1]x[0,1] bounds. + */ + private boolean isShape(Path maskPath) { + // Condition: + // Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation + // should generate transparent image, if the actual icon is equivalent to the shape. + mFileId = mRandom.nextInt(); + mBitmapARGB.eraseColor(Color.TRANSPARENT); + mCanvasARGB.drawBitmap(mBitmap, 0, 0, mPaintIcon); + + // Fit the shape within the icon's bounding box + mMatrix.reset(); + float matrixScale = Math.max(mBounds.width(), mBounds.height()); + mMatrix.setScale(matrixScale, matrixScale); + mMatrix.postTranslate(mBounds.left - (matrixScale - mBounds.width())/2, + mBounds.top - (matrixScale - mBounds.height())/2); + maskPath.transform(mMatrix); + + // XOR operation + mCanvasARGB.drawPath(maskPath, mPaintMaskShape); + + // DST_OUT operation around the mask path outline + mCanvasARGB.drawPath(maskPath, mPaintMaskShapeOutline); + + boolean isTrans = isTransparentBitmap(mBitmapARGB); + + // Check if the result is almost transparent + if (!isTrans) { + return false; + } + return true; + } + + /** + * Used to determine if certain the bitmap is transparent. + */ + public boolean isTransparentBitmap(Bitmap bitmap) { + int w = mBounds.width(); + int h = mBounds.height(); + try { + bitmap.getPixels(mPixelsARGB, 0 /* the first index to write into the array */, + w /* stride */, + mBounds.left, mBounds.top, + w, h); + } catch (Exception e) { + return false; + } + int sum = 0; + for (int i = 0; i < w * h; i++) { + if(Color.alpha(mPixelsARGB[i]) > MIN_VISIBLE_ALPHA) { + sum++; + } + } + float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height()); + boolean transparentImage = percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD; + + return transparentImage; + } + + /** + * Returns the amount by which the {@param d} should be scaled (in both dimensions) so that it + * matches the design guidelines for a launcher icon. + * + * We first calculate the convex hull of the visible portion of the icon. + * This hull then compared with the bounding rectangle of the hull to find how closely it + * resembles a circle and a square, by comparing the ratio of the areas. Note that this is not an + * ideal solution but it gives satisfactory result without affecting the performance. + * + * This closeness is used to determine the ratio of hull area to the full icon size. + * Refer {@link #MAX_CIRCLE_AREA_FACTOR} and {@link #MAX_SQUARE_AREA_FACTOR} + * + * @param outBounds optional rect to receive the fraction distance from each edge. + */ + public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds, + @Nullable Path path, @Nullable boolean[] outMaskShape) { + if (d instanceof AdaptiveIconDrawable && + mAdaptiveIconScale != SCALE_NOT_INITIALIZED) { + if (outBounds != null) { + outBounds.set(mAdaptiveIconBounds); + } + return mAdaptiveIconScale; + } + int width = d.getIntrinsicWidth(); + int height = d.getIntrinsicHeight(); + if (width <= 0 || height <= 0) { + width = width <= 0 || width > mMaxSize ? mMaxSize : width; + height = height <= 0 || height > mMaxSize ? mMaxSize : height; + } else if (width > mMaxSize || height > mMaxSize) { + int max = Math.max(width, height); + width = mMaxSize * width / max; + height = mMaxSize * height / max; + } + + mBitmap.eraseColor(Color.TRANSPARENT); + d.setBounds(0, 0, width, height); + d.draw(mCanvas); + + ByteBuffer buffer = ByteBuffer.wrap(mPixels); + buffer.rewind(); + mBitmap.copyPixelsToBuffer(buffer); + + // Overall bounds of the visible icon. + int topY = -1; + int bottomY = -1; + int leftX = mMaxSize + 1; + int rightX = -1; + + // Create border by going through all pixels one row at a time and for each row find + // the first and the last non-transparent pixel. Set those values to mLeftBorder and + // mRightBorder and use -1 if there are no visible pixel in the row. + + // buffer position + int index = 0; + // buffer shift after every row, width of buffer = mMaxSize + int rowSizeDiff = mMaxSize - width; + // first and last position for any row. + int firstX, lastX; + + for (int y = 0; y < height; y++) { + firstX = lastX = -1; + for (int x = 0; x < width; x++) { + if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) { + if (firstX == -1) { + firstX = x; + } + lastX = x; + } + index++; + } + index += rowSizeDiff; + + mLeftBorder[y] = firstX; + mRightBorder[y] = lastX; + + // If there is at least one visible pixel, update the overall bounds. + if (firstX != -1) { + bottomY = y; + if (topY == -1) { + topY = y; + } + + leftX = Math.min(leftX, firstX); + rightX = Math.max(rightX, lastX); + } + } + + if (topY == -1 || rightX == -1) { + // No valid pixels found. Do not scale. + return 1; + } + + convertToConvexArray(mLeftBorder, 1, topY, bottomY); + convertToConvexArray(mRightBorder, -1, topY, bottomY); + + // Area of the convex hull + float area = 0; + for (int y = 0; y < height; y++) { + if (mLeftBorder[y] <= -1) { + continue; + } + area += mRightBorder[y] - mLeftBorder[y] + 1; + } + + // Area of the rectangle required to fit the convex hull + float rectArea = (bottomY + 1 - topY) * (rightX + 1 - leftX); + float hullByRect = area / rectArea; + + float scaleRequired; + if (hullByRect < CIRCLE_AREA_BY_RECT) { + scaleRequired = MAX_CIRCLE_AREA_FACTOR; + } else { + scaleRequired = MAX_SQUARE_AREA_FACTOR + LINEAR_SCALE_SLOPE * (1 - hullByRect); + } + mBounds.left = leftX; + mBounds.right = rightX; + + mBounds.top = topY; + mBounds.bottom = bottomY; + + if (outBounds != null) { + outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top), + 1 - ((float) mBounds.right) / width, + 1 - ((float) mBounds.bottom) / height); + } + + if (outMaskShape != null && outMaskShape.length > 0) { + outMaskShape[0] = isShape(path); + } + float areaScale = area / (width * height); + // Use sqrt of the final ratio as the images is scaled across both width and height. + float scale = areaScale > scaleRequired ? (float) Math.sqrt(scaleRequired / areaScale) : 1; + if (d instanceof AdaptiveIconDrawable && + mAdaptiveIconScale == SCALE_NOT_INITIALIZED) { + mAdaptiveIconScale = scale; + mAdaptiveIconBounds.set(mBounds); + } + return scale; + } + + /** + * Modifies {@param xCoordinates} to represent a convex border. Fills in all missing values + * (except on either ends) with appropriate values. + * @param xCoordinates map of x coordinate per y. + * @param direction 1 for left border and -1 for right border. + * @param topY the first Y position (inclusive) with a valid value. + * @param bottomY the last Y position (inclusive) with a valid value. + */ + private static void convertToConvexArray( + float[] xCoordinates, int direction, int topY, int bottomY) { + int total = xCoordinates.length; + // The tangent at each pixel. + float[] angles = new float[total - 1]; + + int first = topY; // First valid y coordinate + int last = -1; // Last valid y coordinate which didn't have a missing value + + float lastAngle = Float.MAX_VALUE; + + for (int i = topY + 1; i <= bottomY; i++) { + if (xCoordinates[i] <= -1) { + continue; + } + int start; + + if (lastAngle == Float.MAX_VALUE) { + start = first; + } else { + float currentAngle = (xCoordinates[i] - xCoordinates[last]) / (i - last); + start = last; + // If this position creates a concave angle, keep moving up until we find a + // position which creates a convex angle. + if ((currentAngle - lastAngle) * direction < 0) { + while (start > first) { + start --; + currentAngle = (xCoordinates[i] - xCoordinates[start]) / (i - start); + if ((currentAngle - angles[start]) * direction >= 0) { + break; + } + } + } + } + + // Reset from last check + lastAngle = (xCoordinates[i] - xCoordinates[start]) / (i - start); + // Update all the points from start. + for (int j = start; j < i; j++) { + angles[j] = lastAngle; + xCoordinates[j] = xCoordinates[start] + lastAngle * (j - start); + } + last = i; + } + } +} diff --git a/core/java/com/android/internal/icons/IconsHandler.java b/core/java/com/android/internal/icons/IconsHandler.java new file mode 100644 index 000000000000..16822eef0a33 --- /dev/null +++ b/core/java/com/android/internal/icons/IconsHandler.java @@ -0,0 +1,463 @@ +/* + * Copyright (C) 2017 Paranoid Android + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.icons; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.LauncherActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Process; +import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; + +import com.android.internal.icons.RecentPanelIcons; + +import org.xmlpull.v1.XmlPullParser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class IconsHandler { + + private static final String TAG = "IconsHandler"; + + private Map mIconPacks = new HashMap<>(); + private Map mAppFilterDrawables = new HashMap<>(); + private List mBackImages = new ArrayList<>(); + private List mDrawables = new ArrayList<>(); + + private Bitmap mFrontImage; + private Bitmap mMaskImage; + + private Resources mCurrentIconPackRes; + private Resources mOriginalIconPackRes; + private String mIconPackPackageName = ""; + + private Context mContext; + private PackageManager mPackageManager; + + private float mFactor = 1.0f; + + private int mIconSizeId; + + private float mScaleFactor; + + private IconNormalizer mIconNormalizer; + private ShadowGenerator mShadowGenerator; + + public IconsHandler(Context context, int iconSizeId, float scaleFactor) { + mContext = context; + if (iconSizeId == -1) iconSizeId = com.android.internal.R.dimen.app_icon_size; + mIconSizeId = iconSizeId; + mScaleFactor = scaleFactor; + mPackageManager = context.getPackageManager(); + mIconNormalizer = new IconNormalizer(context, iconSizeId, scaleFactor); + mShadowGenerator = new ShadowGenerator(context, iconSizeId, scaleFactor); + } + + public void setScaleFactor(float scaleFactor) { + mIconNormalizer = new IconNormalizer(mContext, mIconSizeId, scaleFactor); + mShadowGenerator = new ShadowGenerator(mContext, mIconSizeId, scaleFactor); + updatePrefs(mIconPackPackageName, true); + } + + private void loadIconPack(String packageName, boolean fallback) { + mIconPackPackageName = packageName; + if (!fallback) { + mAppFilterDrawables.clear(); + mBackImages.clear(); + } else { + mDrawables.clear(); + } + mFactor = 1.0f; + + XmlPullParser xpp = null; + + try { + mOriginalIconPackRes = mPackageManager.getResourcesForApplication(mIconPackPackageName); + mCurrentIconPackRes = mOriginalIconPackRes; + int appfilterid = mOriginalIconPackRes.getIdentifier("appfilter", "xml", mIconPackPackageName); + if (appfilterid > 0) { + xpp = mOriginalIconPackRes.getXml(appfilterid); + } + + if (xpp != null) { + int eventType = xpp.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + if (!fallback & xpp.getName().equals("iconback")) { + for (int i = 0; i < xpp.getAttributeCount(); i++) { + if (xpp.getAttributeName(i).startsWith("img")) { + String drawableName = xpp.getAttributeValue(i); + Bitmap iconback = loadBitmap(drawableName); + if (iconback != null) { + mBackImages.add(iconback); + } + } + } + } else if (!fallback && xpp.getName().equals("iconmask")) { + if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("img1")) { + String drawableName = xpp.getAttributeValue(0); + mMaskImage = loadBitmap(drawableName); + } + } else if (!fallback && xpp.getName().equals("iconupon")) { + if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("img1")) { + String drawableName = xpp.getAttributeValue(0); + mFrontImage = loadBitmap(drawableName); + } + } else if (!fallback && xpp.getName().equals("scale")) { + if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("factor")) { + mFactor = Float.valueOf(xpp.getAttributeValue(0)); + } + } + if (xpp.getName().equals("item")) { + String componentName = null; + String drawableName = null; + + for (int i = 0; i < xpp.getAttributeCount(); i++) { + if (xpp.getAttributeName(i).equals("component")) { + componentName = xpp.getAttributeValue(i); + } else if (xpp.getAttributeName(i).equals("drawable")) { + drawableName = xpp.getAttributeValue(i); + } + } + if (fallback && getIdentifier(packageName, drawableName, true) > 0 + && !mDrawables.contains(drawableName)) { + mDrawables.add(drawableName); + } + if (!fallback && componentName != null && drawableName != null && + !mAppFilterDrawables.containsKey(componentName)) { + mAppFilterDrawables.put(componentName, drawableName); + } + } + } + eventType = xpp.next(); + } + } + } catch (Exception e) { + Log.e(TAG, "Error parsing appfilter.xml " + e); + } + } + + public BitmapDrawable getBitmap(Context context, Drawable drawable) { + if (drawable != null && drawable instanceof BitmapDrawable) { + Bitmap bm = ((BitmapDrawable) drawable).getBitmap(); + return new BitmapDrawable(context.getResources(), RecentPanelIcons.createIconBitmap(bm, context, mIconNormalizer, mShadowGenerator)); + } + return null; + } + + public Drawable getIconFromHandler(Context context, ActivityInfo info) { + final String packageName = info.applicationInfo.packageName; + ComponentName defaultName = getDefaultName(packageName); + ComponentName name = null; + try{ + name = new ComponentName(packageName, info.name); + } catch (Exception e) {} + + return getBitmap(packageName, name, defaultName, context); + } + + public Drawable getIconFromHandler(Context context, LauncherActivityInfo info) { + final String packageName = info.getApplicationInfo().packageName; + ComponentName defaultName = getDefaultName(packageName); + ComponentName name = info.getComponentName(); + + return getBitmap(packageName, name, defaultName, context); + } + + public Drawable getIconFromHandler(Context context, ApplicationInfo info, String packageName) { + ComponentName defaultName = getDefaultName(packageName); + ComponentName name = null; + try{ + name = new ComponentName(packageName, info.name); + } catch (Exception e) {} + + return getBitmap(packageName, name, defaultName, context); + } + + private BitmapDrawable getBitmap(String packageName, ComponentName name, ComponentName defaultName, Context context) { + Bitmap bm = getDrawableIconForPackage(packageName, name, defaultName); + if (bm == null) { + return null; + } + return new BitmapDrawable(context.getResources(), RecentPanelIcons.createIconBitmap(bm, context, mIconNormalizer, mShadowGenerator)); + } + + public ComponentName getDefaultName(String packageName) { + Intent launchIntent = mPackageManager.getLaunchIntentForPackage(packageName); + ComponentName defaultName = null; + if (launchIntent != null) { + defaultName = launchIntent.getComponent(); + } + return defaultName; + } + + public List getAllDrawables(final String packageName) { + loadIconPack(packageName, true); + Collections.sort(mDrawables, new Comparator() { + @Override + public int compare(String drawable, String drawable2) { + return drawable.compareToIgnoreCase(drawable2); + } + }); + + return mDrawables; + } + + public boolean isDefaultIconPack() { + return mIconPackPackageName.equalsIgnoreCase(""); + } + + private int getIdentifier(String packageName, String drawableName, boolean currentIconPack) { + if (drawableName == null) { + return 0; + } + if (packageName == null) { + packageName = mIconPackPackageName; + } + return (!currentIconPack ? mOriginalIconPackRes : mCurrentIconPackRes).getIdentifier( + drawableName, "drawable", packageName); + } + + public Drawable loadDrawable(String packageName, String drawableName, boolean currentIconPack) { + if (packageName == null) { + packageName = mIconPackPackageName; + } + int id = getIdentifier(packageName, drawableName, currentIconPack); + if (id > 0) { + return (!currentIconPack ? mOriginalIconPackRes : mCurrentIconPackRes).getDrawable(id, mContext.getTheme()); + } + return null; + } + + private Bitmap loadBitmap(String drawableName) { + Drawable bitmap = loadDrawable(null, drawableName, true); + if (bitmap != null && bitmap instanceof BitmapDrawable) { + return ((BitmapDrawable) bitmap).getBitmap(); + } + return null; + } + + private Bitmap getDefaultAppDrawable(ComponentName componentName) { + Drawable drawable = null; + try { + drawable = mPackageManager.getApplicationIcon(mPackageManager.getApplicationInfo( + componentName.getPackageName(), 0)); + } catch (NameNotFoundException e) { + Log.e(TAG, "Unable to find component " + componentName.toString() + e); + } + if (drawable == null) { + return null; + } + + return generateBitmap(componentName, RecentPanelIcons.createIconBitmap(drawable, mContext, mIconNormalizer, mShadowGenerator)); + } + + public Bitmap getDrawableIconForPackage(String packageName, ComponentName componentName, ComponentName defaultName) { + String drawableName = null; + if (componentName != null) { + drawableName = mAppFilterDrawables.get(componentName.toString()); + } + if (drawableName == null && defaultName != null) { + drawableName = mAppFilterDrawables.get(defaultName.toString()); + } + if (drawableName == null && packageName != null) { + drawableName = mAppFilterDrawables.get(packageName.toString()); + } + Drawable drawable = loadDrawable(null, drawableName, false); + if (drawable != null && drawable instanceof BitmapDrawable) { + Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); + return bitmap; + } + + if (componentName == null) return null; + + return getDefaultAppDrawable(componentName); + } + + private Bitmap generateBitmap(ComponentName componentName, Bitmap defaultBitmap) { + Drawable d = new BitmapDrawable(mContext.getResources(), defaultBitmap); + if (mBackImages.isEmpty()) { + return RecentPanelIcons.createBadgedIconBitmap(mIconNormalizer, mShadowGenerator, d, Process.myUserHandle(), + mContext, Build.VERSION.SDK_INT, true, isDefaultIconPack()); + } + + Bitmap wrapped = RecentPanelIcons.createBadgedIconBitmap(mIconNormalizer, mShadowGenerator, d, Process.myUserHandle(), + mContext, Build.VERSION.SDK_INT, false, isDefaultIconPack()); + + Random random = new Random(); + int id = random.nextInt(mBackImages.size()); + Bitmap backImage = mBackImages.get(id); + int w = backImage.getWidth(); + int h = backImage.getHeight(); + + Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(result); + canvas.drawBitmap(backImage, 0, 0, null); + + if (!mIconNormalizer.isTransparentBitmap(backImage)) { + mFactor = 0.7f; + } + Bitmap scaledBitmap = Bitmap.createScaledBitmap(wrapped, + (int) (w * mFactor), (int) (h * mFactor), false); + + Bitmap mutableMask = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + Canvas maskCanvas = new Canvas(mutableMask); + Bitmap targetBitmap = mMaskImage == null ? mutableMask : mMaskImage; + maskCanvas.drawBitmap(targetBitmap, 0, 0, new Paint()); + + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST)); + canvas.drawBitmap(scaledBitmap, (w - scaledBitmap.getWidth()) / 2, + (h - scaledBitmap.getHeight()) / 2, null); + canvas.drawBitmap(mutableMask, 0, 0, paint); + + if (mFrontImage != null) { + canvas.drawBitmap(mFrontImage, 0, 0, null); + } + return result; + } + + public void updatePrefs(String iconPack) { + updatePrefs(iconPack, false); + } + + public void updatePrefs(String iconPack, boolean force) { + if (iconPack == null || (!force && iconPack.equals(mIconPackPackageName))) { + return; + } + mIconPackPackageName = iconPack; + if (!TextUtils.isEmpty(iconPack) || TextUtils.isEmpty(mIconPackPackageName)) { + refresh(); + } + if (!TextUtils.isEmpty(mIconPackPackageName)) { + loadIconPack(iconPack, false); + } + } + + public void refresh() { + mAppFilterDrawables.clear(); + mBackImages.clear(); + mDrawables.clear(); + mFrontImage = null; + mMaskImage = null; + mCurrentIconPackRes = null; + mOriginalIconPackRes = null; + } + + public void onDpiChanged(Context ctx) { + mContext = ctx; + mIconNormalizer = new IconNormalizer(ctx, mIconSizeId, mScaleFactor); + mShadowGenerator = new ShadowGenerator(ctx, mIconSizeId, mScaleFactor); + updatePrefs(mIconPackPackageName, true); + } + + public List getMatchingDrawables(String packageName) { + List matchingDrawables = new ArrayList<>(); + ApplicationInfo info = null; + try { + info = mPackageManager.getApplicationInfo(packageName, 0); + } catch (NameNotFoundException e) { + e.printStackTrace(); + } + String packageLabel = (info != null ? mPackageManager.getApplicationLabel(info).toString() + : packageName).replaceAll("[^a-zA-Z]", "").toLowerCase().trim(); + for (String drawable : mDrawables) { + if (drawable == null) continue; + String filteredDrawable = drawable.replaceAll("[^a-zA-Z]", "").toLowerCase().trim(); + if (filteredDrawable.length() > 2 && (packageLabel.contains(filteredDrawable) + || filteredDrawable.contains(packageLabel))) { + matchingDrawables.add(drawable); + } + } + return matchingDrawables; + } + + public Pair, List> getAllIconPacks() { + // Ensure to update the icon packs list + loadAvailableIconPacks(); + + List iconPackNames = new ArrayList<>(); + List iconPackLabels = new ArrayList<>(); + List iconPacks = new ArrayList(mIconPacks.values()); + Collections.sort(iconPacks, new Comparator() { + @Override + public int compare(IconPackInfo info, IconPackInfo info2) { + return info.label.toString().compareToIgnoreCase(info2.label.toString()); + } + }); + for (IconPackInfo info : iconPacks) { + iconPackNames.add(info.packageName); + iconPackLabels.add(info.label.toString()); + } + return new Pair<>(iconPackNames, iconPackLabels); + } + + private void loadAvailableIconPacks() { + // Remove all elements from global icon pack variable. + mIconPacks.clear(); + List list; + list = mPackageManager.queryIntentActivities(new Intent("com.novalauncher.THEME"), 0); + list.addAll(mPackageManager.queryIntentActivities(new Intent("org.adw.launcher.icons.ACTION_PICK_ICON"), 0)); + list.addAll(mPackageManager.queryIntentActivities(new Intent("com.dlto.atom.launcher.THEME"), 0)); + list.addAll(mPackageManager.queryIntentActivities(new Intent("android.intent.action.MAIN").addCategory("com.anddoes.launcher.THEME"), 0)); + for (ResolveInfo info : list) { + mIconPacks.put(info.activityInfo.packageName, new IconPackInfo(info, mPackageManager)); + } + } + + public static class IconPackInfo { + public String packageName; + public CharSequence label; + public Drawable icon; + + public IconPackInfo(ResolveInfo r, PackageManager packageManager) { + packageName = r.activityInfo.packageName; + icon = r.loadIcon(packageManager); + label = r.loadLabel(packageManager); + } + + public IconPackInfo(String label, Drawable icon, String packageName) { + this.label = label; + this.icon = icon; + this.packageName = packageName; + } + } +} diff --git a/core/java/com/android/internal/icons/RecentPanelIcons.java b/core/java/com/android/internal/icons/RecentPanelIcons.java new file mode 100644 index 000000000000..617a640d280f --- /dev/null +++ b/core/java/com/android/internal/icons/RecentPanelIcons.java @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.icons; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PaintFlagsDrawFilter; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.PaintDrawable; +import android.os.Process; +import android.os.UserHandle; + +/** + * Helper methods for generating various launcher icons + */ +public class RecentPanelIcons { + + private static final Rect sOldBounds = new Rect(); + private static final Canvas sCanvas = new Canvas(); + + static { + sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, + Paint.FILTER_BITMAP_FLAG)); + } + + /** + * Returns a bitmap which is of the appropriate size to be displayed as an icon + */ + public static Bitmap createIconBitmap(Bitmap icon, Context context, + IconNormalizer normalizer, ShadowGenerator shadowGenerator) { + final int iconBitmapSize = (int) (context.getResources() + .getDimensionPixelSize(normalizer.getIconSizeId()) * normalizer.getScaleFactor()); + + if (iconBitmapSize == icon.getWidth() && iconBitmapSize == icon.getHeight()) { + return icon; + } + return createIconBitmap(new BitmapDrawable(context.getResources(), icon), context, normalizer, shadowGenerator); + } + + /** + * Returns a bitmap suitable for the all apps view. The icon is badged for {@param user}. + * The bitmap is also visually normalized with other icons. + */ + + public static Bitmap createBadgedIconBitmap( + IconNormalizer normalizer, ShadowGenerator shadowGenerator, Drawable icon, + UserHandle user, Context context, int iconAppTargetSdk, boolean forceWrap, boolean defaultIconPack) { + float scale = 1f; + boolean[] outShape = new boolean[1]; + AdaptiveIconDrawable dr = (AdaptiveIconDrawable) + context.getDrawable(com.android.internal.R.drawable.adaptive_icon_drawable_wrapper).mutate(); + dr.setBounds(0, 0, 1, 1); + scale = normalizer.getScale(icon, null, dr.getIconMask(), outShape); + if ((forceWrap || defaultIconPack) + && !outShape[0]){ + Drawable wrappedIcon = wrapToAdaptiveIconDrawable(context, icon, scale); + if (wrappedIcon != icon) { + icon = wrappedIcon; + scale = normalizer.getScale(icon, null, null, null); + } + } + Bitmap bitmap = createIconBitmap(icon, context, scale, normalizer, shadowGenerator); + if (icon instanceof AdaptiveIconDrawable) { + bitmap = shadowGenerator.recreateIcon(bitmap); + } + return badgeIconForUser(bitmap, user, context, normalizer, shadowGenerator); + } + + /** + * Badges the provided icon with the user badge if required. + */ + public static Bitmap badgeIconForUser(Bitmap icon, UserHandle user, Context context, + IconNormalizer normalizer, ShadowGenerator shadowGenerator) { + if (user != null && !Process.myUserHandle().equals(user)) { + BitmapDrawable drawable = new FixedSizeBitmapDrawable(icon); + Drawable badged = context.getPackageManager().getUserBadgedIcon( + drawable, user); + if (badged instanceof BitmapDrawable) { + return ((BitmapDrawable) badged).getBitmap(); + } else { + return createIconBitmap(badged, context, normalizer, shadowGenerator); + } + } else { + return icon; + } + } + + /** + * If the platform is running O but the app is not providing AdaptiveIconDrawable, then + * shrink the legacy icon and set it as foreground. Use color drawable as background to + * create AdaptiveIconDrawable. + */ + static Drawable wrapToAdaptiveIconDrawable(Context context, Drawable drawable, float scale) { + try { + if (!(drawable instanceof AdaptiveIconDrawable)) { + AdaptiveIconDrawable iconWrapper = (AdaptiveIconDrawable) + context.getDrawable(com.android.internal.R.drawable.adaptive_icon_drawable_wrapper).mutate(); + FixedScaleDrawable fsd = ((FixedScaleDrawable) iconWrapper.getForeground()); + fsd.setDrawable(drawable); + fsd.setScale(scale); + return (Drawable) iconWrapper; + } + } catch (Exception e) { + return drawable; + } + return drawable; + } + + /** + * Returns a bitmap suitable for the all apps view. + */ + public static Bitmap createIconBitmap(Drawable icon, Context context, + IconNormalizer normalizer, ShadowGenerator shadowGenerator) { + float scale = 1f; + if (icon instanceof AdaptiveIconDrawable) { + scale = ShadowGenerator.getScaleForBounds(new RectF(0, 0, 0, 0)); + } + Bitmap bitmap = createIconBitmap(icon, context, scale, normalizer, shadowGenerator); + if (icon instanceof AdaptiveIconDrawable) { + bitmap = shadowGenerator.recreateIcon(bitmap); + } + return bitmap; + } + + /** + * @param scale the scale to apply before drawing {@param icon} on the canvas + */ + public static Bitmap createIconBitmap(Drawable icon, Context context, float scale, + IconNormalizer normalizer, ShadowGenerator shadowGenerator) { + synchronized (sCanvas) { + final int iconBitmapSize = (int) (context.getResources() + .getDimensionPixelSize(normalizer.getIconSizeId()) * normalizer.getScaleFactor()); + int width = iconBitmapSize; + int height = iconBitmapSize; + + if (icon instanceof PaintDrawable) { + PaintDrawable painter = (PaintDrawable) icon; + painter.setIntrinsicWidth(width); + painter.setIntrinsicHeight(height); + } else if (icon instanceof BitmapDrawable) { + // Ensure the bitmap has a density. + BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; + Bitmap bitmap = bitmapDrawable.getBitmap(); + if (bitmap != null && bitmap.getDensity() == Bitmap.DENSITY_NONE) { + bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics()); + } + } + + int sourceWidth = icon.getIntrinsicWidth(); + int sourceHeight = icon.getIntrinsicHeight(); + if (sourceWidth > 0 && sourceHeight > 0) { + // Scale the icon proportionally to the icon dimensions + final float ratio = (float) sourceWidth / sourceHeight; + if (sourceWidth > sourceHeight) { + height = (int) (width / ratio); + } else if (sourceHeight > sourceWidth) { + width = (int) (height * ratio); + } + } + // no intrinsic size --> use default size + int textureWidth = iconBitmapSize; + int textureHeight = iconBitmapSize; + + Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, + Bitmap.Config.ARGB_8888); + final Canvas canvas = sCanvas; + canvas.setBitmap(bitmap); + + final int left = (textureWidth-width) / 2; + final int top = (textureHeight-height) / 2; + + sOldBounds.set(icon.getBounds()); + if (icon instanceof AdaptiveIconDrawable) { + int offset = Math.max((int)(ShadowGenerator.BLUR_FACTOR * iconBitmapSize), + Math.min(left, top)); + int size = Math.max(width, height); + icon.setBounds(offset, offset, size, size); + } else { + icon.setBounds(left, top, left+width, top+height); + } + canvas.save(Canvas.MATRIX_SAVE_FLAG); + canvas.scale(scale, scale, textureWidth / 2, textureHeight / 2); + icon.draw(canvas); + canvas.restore(); + icon.setBounds(sOldBounds); + canvas.setBitmap(null); + + return bitmap; + } + } + + /** + * An extension of {@link BitmapDrawable} which returns the bitmap pixel size as intrinsic size. + * This allows the badging to be done based on the action bitmap size rather than + * the scaled bitmap size. + */ + private static class FixedSizeBitmapDrawable extends BitmapDrawable { + + public FixedSizeBitmapDrawable(Bitmap bitmap) { + super(null, bitmap); + } + + @Override + public int getIntrinsicHeight() { + return getBitmap().getWidth(); + } + + @Override + public int getIntrinsicWidth() { + return getBitmap().getWidth(); + } + } +} diff --git a/core/java/com/android/internal/icons/ShadowGenerator.java b/core/java/com/android/internal/icons/ShadowGenerator.java new file mode 100644 index 000000000000..d855a0027a03 --- /dev/null +++ b/core/java/com/android/internal/icons/ShadowGenerator.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.icons; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BlurMaskFilter; +import android.graphics.BlurMaskFilter.Blur; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import com.android.internal.graphics.ColorUtils; + +/** + * Utility class to add shadows to bitmaps. + */ +public class ShadowGenerator { + + // Percent of actual icon size + private static final float HALF_DISTANCE = 0.5f; + public static final float BLUR_FACTOR = 0.5f/48; + + // Percent of actual icon size + public static final float KEY_SHADOW_DISTANCE = 1f/48; + private static final int KEY_SHADOW_ALPHA = 61; + + private static final int AMBIENT_SHADOW_ALPHA = 30; + + private static final Object LOCK = new Object(); + // Singleton object guarded by {@link #LOCK} + private static ShadowGenerator sShadowGenerator; + + private final int mIconSize; + + private final Canvas mCanvas; + private final Paint mBlurPaint; + private final Paint mDrawPaint; + private final BlurMaskFilter mDefaultBlurMaskFilter; + + public ShadowGenerator(Context context, int iconSizeId, float scaleFactor) { + mIconSize = (int) (context.getResources() + .getDimensionPixelSize(iconSizeId) * scaleFactor); + mCanvas = new Canvas(); + mBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + mDefaultBlurMaskFilter = new BlurMaskFilter(mIconSize * BLUR_FACTOR, Blur.NORMAL); + } + + public synchronized Bitmap recreateIcon(Bitmap icon) { + return recreateIcon(icon, true, mDefaultBlurMaskFilter, AMBIENT_SHADOW_ALPHA, + KEY_SHADOW_ALPHA); + } + + public synchronized Bitmap recreateIcon(Bitmap icon, boolean resize, + BlurMaskFilter blurMaskFilter, int ambientAlpha, int keyAlpha) { + int width = resize ? mIconSize : icon.getWidth(); + int height = resize ? mIconSize : icon.getHeight(); + int[] offset = new int[2]; + + mBlurPaint.setMaskFilter(blurMaskFilter); + Bitmap shadow = icon.extractAlpha(mBlurPaint, offset); + Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888); + mCanvas.setBitmap(result); + + // Draw ambient shadow + mDrawPaint.setAlpha(ambientAlpha); + mCanvas.drawBitmap(shadow, offset[0], offset[1], mDrawPaint); + + // Draw key shadow + mDrawPaint.setAlpha(keyAlpha); + mCanvas.drawBitmap(shadow, offset[0], offset[1] + KEY_SHADOW_DISTANCE * mIconSize, mDrawPaint); + + // Draw the icon + mDrawPaint.setAlpha(255); + mCanvas.drawBitmap(icon, 0, 0, mDrawPaint); + + mCanvas.setBitmap(null); + return result; + } + + /** + * Returns the minimum amount by which an icon with {@param bounds} should be scaled + * so that the shadows do not get clipped. + */ + public static float getScaleForBounds(RectF bounds) { + float scale = 1; + + // For top, left & right, we need same space. + float minSide = Math.min(Math.min(bounds.left, bounds.right), bounds.top); + if (minSide < BLUR_FACTOR) { + scale = (HALF_DISTANCE - BLUR_FACTOR) / (HALF_DISTANCE - minSide); + } + + float bottomSpace = BLUR_FACTOR + KEY_SHADOW_DISTANCE; + if (bounds.bottom < bottomSpace) { + scale = Math.min(scale, (HALF_DISTANCE - bottomSpace) / (HALF_DISTANCE - bounds.bottom)); + } + return scale; + } + + public static class Builder { + + public final RectF bounds = new RectF(); + public final int color; + + public int ambientShadowAlpha = AMBIENT_SHADOW_ALPHA; + + public float shadowBlur; + + public float keyShadowDistance; + public int keyShadowAlpha = KEY_SHADOW_ALPHA; + public float radius; + + public Builder(int color) { + this.color = color; + } + + public Builder setupBlurForSize(int height) { + shadowBlur = height * 1f / 32; + keyShadowDistance = height * 1f / 16; + return this; + } + + public Bitmap createPill(int width, int height) { + radius = height / 2; + + int centerX = Math.round(width / 2 + shadowBlur); + int centerY = Math.round(radius + shadowBlur + keyShadowDistance); + int center = Math.max(centerX, centerY); + bounds.set(0, 0, width, height); + bounds.offsetTo(center - width / 2, center - height / 2); + + int size = center * 2; + Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888); + drawShadow(new Canvas(result)); + return result; + } + + public void drawShadow(Canvas c) { + Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + p.setColor(color); + + // Key shadow + p.setShadowLayer(shadowBlur, 0, keyShadowDistance, + ColorUtils.setAlphaComponent(Color.BLACK, keyShadowAlpha)); + c.drawRoundRect(bounds, radius, radius, p); + + // Ambient shadow + p.setShadowLayer(shadowBlur, 0, 0, + ColorUtils.setAlphaComponent(Color.BLACK, ambientShadowAlpha)); + c.drawRoundRect(bounds, radius, radius, p); + } + } +} diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java index accfc875956c..5ccc1f53501f 100644 --- a/core/java/com/android/internal/notification/SystemNotificationChannels.java +++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java @@ -152,7 +152,7 @@ public static void createAll(Context context) { NotificationChannel foregroundChannel = new NotificationChannel( FOREGROUND_SERVICE, context.getString(R.string.notification_channel_foreground_service), - NotificationManager.IMPORTANCE_LOW); + NotificationManager.IMPORTANCE_NONE); foregroundChannel.setBlockableSystem(true); channelsList.add(foregroundChannel); diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index a6b29c5f8ce8..67b2a140a866 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -253,6 +253,16 @@ public void clearStats() { mStats = null; } + private void clearAllStats() { + clearStats(); + sStatsXfer = null; + sBatteryBroadcastXfer = null; + for (File f : sFileXfer.keySet()) { + f.delete(); + } + sFileXfer.clear(); + } + public BatteryStats getStats() { if (mStats == null) { load(); @@ -1027,6 +1037,15 @@ private void load() { } } + public void resetStatistics() { + try { + clearAllStats(); + mBatteryInfo.resetStatistics(); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException:", e); + } + } + private static BatteryStatsImpl getStats(IBatteryStats service) { try { ParcelFileDescriptor pfd = service.getStatisticsStream(); diff --git a/core/java/com/android/internal/os/DeviceKeyHandler.java b/core/java/com/android/internal/os/DeviceKeyHandler.java new file mode 100644 index 000000000000..b6c55f3eccb1 --- /dev/null +++ b/core/java/com/android/internal/os/DeviceKeyHandler.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2012 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. + */ + +package com.android.internal.os; + +import android.view.KeyEvent; + +public interface DeviceKeyHandler { + + /** + * Invoked when an unknown key was detected by the system, letting the device handle + * this special keys prior to pass the key to the active app. + * + * @param event The key event to be handled + * @return null if event is consumed, KeyEvent to be handled otherwise + */ + public KeyEvent handleKeyEvent(KeyEvent event); +} diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java index 246a50f6ceac..b0e4ca815df8 100644 --- a/core/java/com/android/internal/os/PowerProfile.java +++ b/core/java/com/android/internal/os/PowerProfile.java @@ -20,6 +20,8 @@ import android.content.Context; import android.content.res.Resources; import android.content.res.XmlResourceParser; +import android.os.SystemProperties; +import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; @@ -37,6 +39,7 @@ * [hidden] */ public class PowerProfile { + private static final String TAG = "PowerProfile"; /* * POWER_CPU_SUSPEND: Power consumption when CPU is in power collapse mode. @@ -243,8 +246,9 @@ public PowerProfile(Context context, boolean forTest) { } private void readPowerValuesFromXml(Context context, boolean forTest) { - final int id = forTest ? com.android.internal.R.xml.power_profile_test : + int stockId = forTest ? com.android.internal.R.xml.power_profile_test : com.android.internal.R.xml.power_profile; + final int id = getPowerProfileResId(context, stockId); final Resources resources = context.getResources(); XmlResourceParser parser = resources.getXml(id); boolean parsingArray = false; @@ -403,6 +407,27 @@ public double getAveragePowerForCpuCore(int cluster, int step) { return 0; } + private int getPowerProfileResId(final Context context, int id) { + /* + * If ro.power_profile.override is set, use it to override the default. + * This is used for devices, which need to dynamically define the power profile. + */ + String powerProfileOverride = SystemProperties.get("ro.power_profile.override"); + if (!powerProfileOverride.isEmpty()) { + int tmpId = context.getResources().getIdentifier(powerProfileOverride, "xml", + "android"); + if (tmpId > 0) { + Slog.i(TAG, "getPowerProfileResId: using power profile \"" + + powerProfileOverride + "\""); + id = tmpId; + } else { + Slog.e(TAG, "getPowerProfileResId: could not retrieve power profile \"" + + powerProfileOverride + "\", using default instead"); + } + } + return id; + } + /** * Returns the number of memory bandwidth buckets defined in power_profile.xml, or a * default value if the subsystem has no recorded value. diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index a9cd5c8e4adc..4ab21d8d128d 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -198,6 +198,8 @@ protected static final void commonInit() { Thread.setUncaughtExceptionPreHandler(loggingHandler); Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler)); + Build.adjustBuildTypeIfNeeded(); + /* * Install a TimezoneGetter subclass for ZoneInfo.db */ diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index a8ad8102c610..c46f86792764 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -137,6 +137,7 @@ public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, mDismissStartTarget = mTargets.get(0); mDismissEndTarget = mTargets.get(mTargets.size() - 1); mMiddleTarget = mTargets.get(mTargets.size() / 2); + mMiddleTarget.isMiddleTarget = true; } /** @@ -438,6 +439,8 @@ public static class SnapTarget { public final int flag; + public boolean isMiddleTarget; + /** * Multiplier used to calculate distance to snap position. The lower this value, the harder * it's to snap on this target diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index daea9a8eff41..51b7f1df03dd 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -41,6 +41,7 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.SearchEvent; +import android.view.Surface; import android.view.SurfaceHolder.Callback2; import android.view.View; import android.view.ViewConfiguration; @@ -1874,6 +1875,30 @@ protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) { // If we have a session send it the volume command, otherwise // use the suggested stream. if (mMediaController != null) { + int direction = 0; + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + direction = AudioManager.ADJUST_RAISE; + break; + case KeyEvent.KEYCODE_VOLUME_DOWN: + direction = AudioManager.ADJUST_LOWER; + break; + case KeyEvent.KEYCODE_VOLUME_MUTE: + direction = AudioManager.ADJUST_TOGGLE_MUTE; + break; + } + final int rotation = getWindowManager().getDefaultDisplay().getRotation(); + final Configuration config = getContext().getResources().getConfiguration(); + final boolean swapKeys = Settings.System.getInt(getContext().getContentResolver(), + Settings.System.SWAP_VOLUME_BUTTONS, 0) == 1; + + if (swapKeys + && (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_180) + && config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) { + direction = keyCode == KeyEvent.KEYCODE_VOLUME_UP + ? AudioManager.ADJUST_LOWER + : AudioManager.ADJUST_RAISE; + } mMediaController.dispatchVolumeButtonEventAsSystemService(event); } else { getMediaSessionManager().dispatchVolumeKeyEventAsSystemService(event, diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 2790324e860e..85131a4afe14 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -17,6 +17,7 @@ package com.android.internal.statusbar; import android.content.ComponentName; +import android.content.Intent; import android.graphics.Rect; import android.hardware.biometrics.IBiometricPromptReceiver; import android.os.Bundle; @@ -34,6 +35,7 @@ oneway interface IStatusBar void animateExpandSettingsPanel(String subPanel); void animateCollapsePanels(); void togglePanel(); + void toggleSettingsPanel(); void showWirelessChargingAnimation(int batteryLevel); @@ -97,6 +99,7 @@ oneway interface IStatusBar void showAssistDisclosure(); void startAssist(in Bundle args); + void restartUI(); /** * Notifies the status bar that a camera launch gesture has been detected. @@ -150,4 +153,21 @@ oneway interface IStatusBar void onFingerprintError(String error); // Used to hide the fingerprint dialog when the authenticationclient is stopped void hideFingerprintDialog(); + + /** + * AOSiP + */ + void toggleCameraFlash(); + void toggleCameraFlashState(boolean enable); + + // Used to show or hide in display fingerprint view + void showInDisplayFingerprintView(); + void hideInDisplayFingerprintView(); + + // Start SmartNav API + void screenPinningStateChanged(boolean enabled); + void leftInLandscapeChanged(boolean isLeft); + void toggleFlashlight(); + void toggleNavigationEditor(); + void dispatchNavigationEditorResults(in Intent intent); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 159d49bc0009..a84bcd7f2041 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -17,6 +17,7 @@ package com.android.internal.statusbar; import android.content.ComponentName; +import android.content.Intent; import android.graphics.Rect; import android.os.Bundle; import android.service.notification.StatusBarNotification; @@ -33,6 +34,7 @@ interface IStatusBarService void expandNotificationsPanel(); void collapsePanels(); void togglePanel(); + void toggleSettingsPanel(); void disable(int what, IBinder token, String pkg); void disableForUser(int what, IBinder token, String pkg, int userId); void disable2(int what, IBinder token, String pkg); @@ -78,6 +80,7 @@ interface IStatusBarService */ void shutdown(); void reboot(boolean safeMode); + void advancedReboot(String mode); void addTile(in ComponentName tile); void remTile(in ComponentName tile); @@ -100,4 +103,27 @@ interface IStatusBarService void onFingerprintError(String error); // Used to hide the fingerprint dialog when the authenticationclient is stopped void hideFingerprintDialog(); + + /** + * AOSiP + */ + void toggleCameraFlash(); + void toggleCameraFlashState(boolean enable); + void restartUI(); + + // Used to show or hide in display fingerprint view + void showInDisplayFingerprintView(); + void hideInDisplayFingerprintView(); + + // Start SmartNav methods + void toggleRecentApps(); + void toggleSplitScreen(); + void preloadRecentApps(); + void cancelPreloadRecentApps(); + void startAssist(in Bundle args); + void screenPinningStateChanged(boolean enabled); + void leftInLandscapeChanged(boolean isLeft); + void toggleFlashlight(); + void toggleNavigationEditor(); + void dispatchNavigationEditorResults(in Intent intent); } diff --git a/core/java/com/android/internal/statusbar/ThemeAccentUtils.java b/core/java/com/android/internal/statusbar/ThemeAccentUtils.java new file mode 100644 index 000000000000..ee50abbe2b88 --- /dev/null +++ b/core/java/com/android/internal/statusbar/ThemeAccentUtils.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.statusbar; + +import android.content.om.IOverlayManager; +import android.content.om.OverlayInfo; +import android.os.RemoteException; + +public class ThemeAccentUtils { + + public static final String TAG = "ThemeAccentUtils"; + + // Vendor overlays to ignore + public static final String[] BLACKLIST_VENDOR_OVERLAYS = { + "SysuiDarkTheme", + "Pixel", + "DisplayCutoutEmulationCorner", + "DisplayCutoutEmulationDouble", + "DisplayCutoutEmulationNarrow", + "DisplayCutoutEmulationWide", + }; + + // Stock dark theme package + private static final String STOCK_DARK_THEME = "com.android.systemui.theme.dark"; + + // Light themes + private static final String[] LIGHT_THEMES = { + "com.google.intelligence.sense.theme.light", // 0 + "com.android.gboard.theme.light", // 1 + }; + + // Dark themes + private static final String[] DARK_THEMES = { + "com.android.system.theme.dark", // 0 + "com.android.systemui.theme.custom.dark", // 1 + "com.android.settings.theme.dark", // 2 + "com.android.settings.intelligence.theme.dark", // 3 + "com.android.gboard.theme.dark", // 4 + "com.google.intelligence.sense.theme.dark", // 5 + "com.android.updater.theme.dark", // 6 + "com.android.wellbeing.theme.dark", // 7 + }; + + // BlackAF themes + private static final String[] BLACKAF_THEMES = { + "com.android.system.theme.blackaf", // 0 + "com.android.systemui.theme.custom.blackaf", // 1 + "com.android.settings.theme.blackaf", // 2 + "com.android.settings.intelligence.theme.blackaf", // 3 + "com.android.gboard.theme.blackaf", // 4 + "com.google.intelligence.sense.theme.blackaf", // 5 + "com.android.updater.theme.blackaf", // 6 + "com.android.wellbeing.theme.blackaf", // 7 + }; + + private static final String[] QS_TILE_THEMES = { + "default_qstile", // 0 + "com.android.systemui.qstile.squircle", // 1 + "com.android.systemui.qstile.teardrop", // 2 + "com.android.systemui.qstile.deletround", // 3 + "com.android.systemui.qstile.inktober", // 4 + "com.android.systemui.qstile.shishunights", // 5 + "com.android.systemui.qstile.circledualtone", // 6 + "com.android.systemui.qstile.dottedcircle", // 7 + "com.android.systemui.qstile.shishuink", // 8 + "com.android.systemui.qstile.attemptmountain", // 9 + }; + + // Unloads the stock dark theme + public static void unloadStockDarkTheme(IOverlayManager om, int userId) { + OverlayInfo themeInfo = null; + try { + themeInfo = om.getOverlayInfo(STOCK_DARK_THEME, + userId); + if (themeInfo != null && themeInfo.isEnabled()) { + om.setEnabled(STOCK_DARK_THEME, + false /*disable*/, userId); + } + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + // Check for the dark system theme + public static boolean isUsingDarkTheme(IOverlayManager om, int userId) { + OverlayInfo themeInfo = null; + try { + themeInfo = om.getOverlayInfo(DARK_THEMES[0], + userId); + } catch (RemoteException e) { + e.printStackTrace(); + } + return themeInfo != null && themeInfo.isEnabled(); + } + + // Check for the blackaf system theme + public static boolean isUsingBlackAFTheme(IOverlayManager om, int userId) { + OverlayInfo themeInfo = null; + try { + themeInfo = om.getOverlayInfo(BLACKAF_THEMES[0], + userId); + } catch (RemoteException e) { + e.printStackTrace(); + } + return themeInfo != null && themeInfo.isEnabled(); + } + + // Set light / dark theme + public static void setLightDarkTheme(IOverlayManager om, int userId, boolean useDarkTheme) { + for (String theme : DARK_THEMES) { + try { + om.setEnabled(theme, + useDarkTheme, userId); + if (useDarkTheme) { + unloadStockDarkTheme(om, userId); + } + } catch (RemoteException e) { + } + } + for (String theme : LIGHT_THEMES) { + try { + om.setEnabled(theme, + !useDarkTheme, userId); + } catch (RemoteException e) { + } + } + } + + // Set black theme + public static void setLightBlackAFTheme(IOverlayManager om, int userId, boolean useBlackAFTheme) { + for (String theme : BLACKAF_THEMES) { + try { + om.setEnabled(theme, + useBlackAFTheme, userId); + if (useBlackAFTheme) { + unloadStockDarkTheme(om, userId); + } + } catch (RemoteException e) { + } + } + } + + // Switches qs tile style to user selected. + public static void updateTileStyle(IOverlayManager om, int userId, int qsTileStyle) { + if (qsTileStyle == 0) { + unlockQsTileStyles(om, userId); + } else { + try { + om.setEnabled(QS_TILE_THEMES[qsTileStyle], + true, userId); + } catch (RemoteException e) { + } + } + } + + // Unload all the qs tile styles + public static void unlockQsTileStyles(IOverlayManager om, int userId) { + // skip index 0 + for (int i = 1; i < QS_TILE_THEMES.length; i++) { + String qstiletheme = QS_TILE_THEMES[i]; + try { + om.setEnabled(qstiletheme, + false /*disable*/, userId); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } + + // Check for any QS tile styles overlay + public static boolean isUsingQsTileStyles(IOverlayManager om, int userId, int qsstyle) { + OverlayInfo themeInfo = null; + try { + themeInfo = om.getOverlayInfo(QS_TILE_THEMES[qsstyle], + userId); + } catch (RemoteException e) { + e.printStackTrace(); + } + return themeInfo != null && themeInfo.isEnabled(); + } +} diff --git a/core/java/com/android/internal/util/DogbinException.java b/core/java/com/android/internal/util/DogbinException.java new file mode 100644 index 000000000000..719e111de4fb --- /dev/null +++ b/core/java/com/android/internal/util/DogbinException.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Potato Open Sauce Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +public class DogbinException extends Exception { + + private static final long serialVersionUID = 666L; + + public DogbinException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/core/java/com/android/internal/util/DogbinUtils.java b/core/java/com/android/internal/util/DogbinUtils.java new file mode 100644 index 000000000000..49b5816e5884 --- /dev/null +++ b/core/java/com/android/internal/util/DogbinUtils.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2018 Potato Open Sauce Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +import android.util.JsonReader; +import android.os.Handler; +import android.os.HandlerThread; + + +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.URL; + +import javax.net.ssl.HttpsURLConnection; + +/** + * Helper functions for uploading to del.dog + */ +public final class DogbinUtils { + private static final String TAG = "DogbinUtils"; + private static final String BASE_URL = "https://del.dog"; + private static final String API_URL = String.format("%s/documents", BASE_URL); + private static Handler handler; + + private DogbinUtils() { + } + + /** + * Uploads {@code content} to dogbin + * + * @param content the content to upload to dogbin + * @param callback the callback to call on success / failure + */ + public static void upload(String content, UploadResultCallback callback) { + getHandler().post(new Runnable() { + @Override + public void run() { + try { + HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(API_URL).openConnection(); + try { + urlConnection.setRequestProperty("Accept-Charset", "UTF-8"); + urlConnection.setDoOutput(true); + + try (OutputStream output = urlConnection.getOutputStream()) { + output.write(content.getBytes("UTF-8")); + } + String key = ""; + try (JsonReader reader = new JsonReader( + new InputStreamReader(urlConnection.getInputStream(), "UTF-8"))) { + reader.beginObject(); + while (reader.hasNext()) { + String name = reader.nextName(); + if (name.equals("key")) { + key = reader.nextString(); + break; + } else { + reader.skipValue(); + } + } + reader.endObject(); + } + if (!key.isEmpty()) { + callback.onSuccess(getUrl(key)); + } else { + String msg = "Failed to upload to dogbin: No key retrieved"; + callback.onFail(msg, new DogbinException(msg)); + } + } finally { + urlConnection.disconnect(); + } + } catch (Exception e) { + callback.onFail("Failed to upload to dogbin", e); + } + } + }); + } + + /** + * Get the view URL from a key + */ + private static String getUrl(String key) { + return String.format("%s/%s", BASE_URL, key); + } + + private static Handler getHandler() { + if (handler == null) { + HandlerThread handlerThread = new HandlerThread("dogbinThread"); + if (!handlerThread.isAlive()) + handlerThread.start(); + handler = new Handler(handlerThread.getLooper()); + } + return handler; + } + + public interface UploadResultCallback { + void onSuccess(String url); + + void onFail(String message, Exception e); + } +} \ No newline at end of file diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 318bccf68f57..e87b49e273c2 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -40,6 +40,7 @@ import android.util.Log; import android.util.Pair; +import com.android.internal.R; import java.util.Arrays; import java.util.WeakHashMap; @@ -470,8 +471,10 @@ public static int resolveColor(Context context, int color) { */ public static int resolveContrastColor(Context context, int notificationColor, int backgroundColor) { + boolean isDark = context.getResources() + .getBoolean(R.bool.config_useDarkBgNotificationIconTextTinting); return NotificationColorUtil.resolveContrastColor(context, notificationColor, - backgroundColor, false /* isDark */); + backgroundColor, isDark); } /** @@ -489,6 +492,8 @@ public static int resolveContrastColor(Context context, int notificationColor, final int resolvedColor = resolveColor(context, notificationColor); int color = resolvedColor; + + isDark = isDark || getDarkNotificationTinting(context); color = NotificationColorUtil.ensureTextContrast(color, backgroundColor, isDark); if (color != resolvedColor) { @@ -623,6 +628,30 @@ public static boolean isColorLight(int backgroundColor) { return calculateLuminance(backgroundColor) > 0.5f; } + public static boolean getDarkNotificationTinting(Context context) { + boolean darkNotificationTinting = context.getResources().getBoolean( + R.bool.config_useDarkBgNotificationIconTextTinting); + boolean override = context.getResources().getBoolean( + R.bool.config_notificationTinting_override); + if (override) { + darkNotificationTinting = context.getResources().getBoolean( + R.bool.config_useDarkBgNotificationTinting_override); + } + return darkNotificationTinting; + } + + public static boolean getNightModeNotification(Context context) { + boolean nightModeNotification = context.getResources().getBoolean( + R.bool.config_enableNightMode); + boolean override = context.getResources().getBoolean( + R.bool.config_notificationTinting_override); + if (override) { + nightModeNotification = context.getResources().getBoolean( + R.bool.config_useDarkBgNotificationTinting_override); + } + return nightModeNotification; + } + /** * Framework copy of functions needed from android.support.v4.graphics.ColorUtils. */ diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index 7fd94c6859fb..b92204236e97 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -1,9 +1,13 @@ package com.android.internal.util; +import static android.content.Intent.ACTION_USER_SWITCHED; + import android.annotation.NonNull; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; @@ -29,8 +33,21 @@ public class ScreenshotHelper { private ServiceConnection mScreenshotConnection = null; private final Context mContext; + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + synchronized (mScreenshotLock) { + if (ACTION_USER_SWITCHED.equals(intent.getAction())) { + resetConnection(); + } + } + } + }; + public ScreenshotHelper(Context context) { mContext = context; + IntentFilter filter = new IntentFilter(ACTION_USER_SWITCHED); + mContext.registerReceiver(mBroadcastReceiver, filter); } /** @@ -57,8 +74,8 @@ public void takeScreenshot(final int screenshotType, final boolean hasStatus, @Override public void run() { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; + Log.e(TAG, "Timed out before getting screenshot capture response"); + resetConnection(); notifyScreenshotError(); } } @@ -81,8 +98,7 @@ public void onServiceConnected(ComponentName name, IBinder service) { public void handleMessage(Message msg) { synchronized (mScreenshotLock) { if (mScreenshotConnection == myConn) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; + resetConnection(); handler.removeCallbacks(mScreenshotTimeout); } } @@ -103,8 +119,7 @@ public void handleMessage(Message msg) { public void onServiceDisconnected(ComponentName name) { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; + resetConnection(); handler.removeCallbacks(mScreenshotTimeout); notifyScreenshotError(); } @@ -120,6 +135,16 @@ public void onServiceDisconnected(ComponentName name) { } } + /** + * Unbinds the current screenshot connection (if any). + */ + private void resetConnection() { + if (mScreenshotConnection != null) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + } + } + /** * Notifies the screenshot service to show an error. */ diff --git a/core/java/com/android/internal/util/UserIcons.java b/core/java/com/android/internal/util/UserIcons.java index bfe43237da58..d921290efd1a 100644 --- a/core/java/com/android/internal/util/UserIcons.java +++ b/core/java/com/android/internal/util/UserIcons.java @@ -73,7 +73,7 @@ public static Drawable getDefaultUserIcon(Resources resources, int userId, boole colorResId = USER_ICON_COLORS[userId % USER_ICON_COLORS.length]; } Drawable icon = resources.getDrawable(R.drawable.ic_account_circle, null).mutate(); - icon.setColorFilter(resources.getColor(colorResId, null), Mode.SRC_IN); + icon.setColorFilter(resources.getColor(colorResId, null), Mode.SRC_ATOP); icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); return icon; } diff --git a/core/java/com/android/internal/util/aosip/Action.java b/core/java/com/android/internal/util/aosip/Action.java new file mode 100644 index 000000000000..051297646724 --- /dev/null +++ b/core/java/com/android/internal/util/aosip/Action.java @@ -0,0 +1,314 @@ + +/* +* Copyright (C) 2014 SlimRoms Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.android.internal.util.aosip; + +import android.app.Activity; +import android.app.ActivityManagerNative; +import android.app.SearchManager; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.hardware.camera2.CameraManager; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraAccessException; +import android.hardware.input.InputManager; +import android.media.AudioManager; +import android.media.session.MediaSessionLegacyHelper; +import android.media.ToneGenerator; +import android.net.Uri; +import android.os.PowerManager; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.os.UserHandle; +import android.os.Vibrator; +import android.provider.Settings; +import android.provider.MediaStore; +import android.util.Log; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.WindowManagerGlobal; + +import com.android.internal.policy.IKeyguardDismissCallback; + +import java.net.URISyntaxException; + +public class Action { + + private static final int MSG_INJECT_KEY_DOWN = 1066; + private static final int MSG_INJECT_KEY_UP = 1067; + + private static boolean sTorchEnabled = false; + + public static void processAction(Context context, String action, boolean isLongpress) { + processActionWithOptions(context, action, isLongpress, true); + } + + public static void processActionWithOptions(Context context, + String action, boolean isLongpress, boolean collapseShade) { + + if (action == null || action.equals(ActionConstants.ACTION_NULL)) { + return; + } + + boolean isKeyguardShowing = false; + try { + isKeyguardShowing = + WindowManagerGlobal.getWindowManagerService().isKeyguardLocked(); + } catch (RemoteException e) { + Log.w("Action", "Error getting window manager service", e); + } + + // process the actions + if (action.equals(ActionConstants.ACTION_HOME)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_HOME, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_BACK)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_BACK, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_SEARCH)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_SEARCH, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_MENU) + || action.equals(ActionConstants.ACTION_MENU_BIG)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_MENU, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_IME_NAVIGATION_LEFT)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_DPAD_LEFT, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_IME_NAVIGATION_RIGHT)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_DPAD_RIGHT, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_IME_NAVIGATION_UP)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_DPAD_UP, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_IME_NAVIGATION_DOWN)) { + triggerVirtualKeypress(KeyEvent.KEYCODE_DPAD_DOWN, isLongpress); + return; + } else if (action.equals(ActionConstants.ACTION_TORCH)) { + try { + CameraManager cameraManager = (CameraManager) + context.getSystemService(Context.CAMERA_SERVICE); + for (final String cameraId : cameraManager.getCameraIdList()) { + CameraCharacteristics characteristics = + cameraManager.getCameraCharacteristics(cameraId); + Boolean flashAvailable = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE); + int orient = characteristics.get(CameraCharacteristics.LENS_FACING); + if (flashAvailable != null && flashAvailable && orient == CameraCharacteristics.LENS_FACING_BACK) { + cameraManager.setTorchMode(cameraId, !sTorchEnabled); + sTorchEnabled = !sTorchEnabled; + break; + } + } + } catch (CameraAccessException e) { + } + return; + } else if (action.equals(ActionConstants.ACTION_POWER)) { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + pm.goToSleep(SystemClock.uptimeMillis()); + return; + } else if (action.equals(ActionConstants.ACTION_IME)) { + if (isKeyguardShowing) { + return; + } + context.sendBroadcastAsUser( + new Intent("android.settings.SHOW_INPUT_METHOD_PICKER"), + new UserHandle(UserHandle.USER_CURRENT)); + return; + } else if (action.equals(ActionConstants.ACTION_VOICE_SEARCH)) { + // launch the search activity + Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + // TODO: This only stops the factory-installed search manager. + // Need to formalize an API to handle others + SearchManager searchManager = + (SearchManager) context.getSystemService(Context.SEARCH_SERVICE); + if (searchManager != null) { + searchManager.stopSearch(); + } + startActivity(context, intent); + } catch (ActivityNotFoundException e) { + Log.e("aosipActions:", "No activity to handle assist long press action.", e); + } + return; + } else if (action.equals(ActionConstants.ACTION_VIB)) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if(am != null && ActivityManagerNative.isSystemReady()) { + if(am.getRingerMode() != AudioManager.RINGER_MODE_VIBRATE) { + am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + Vibrator vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if(vib != null){ + vib.vibrate(50); + } + }else{ + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + ToneGenerator tg = new ToneGenerator( + AudioManager.STREAM_NOTIFICATION, + (int)(ToneGenerator.MAX_VOLUME * 0.85)); + if(tg != null){ + tg.startTone(ToneGenerator.TONE_PROP_BEEP); + } + } + } + return; + } else if (action.equals(ActionConstants.ACTION_SILENT)) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if (am != null && ActivityManagerNative.isSystemReady()) { + if (am.getRingerMode() != AudioManager.RINGER_MODE_SILENT) { + am.setRingerMode(AudioManager.RINGER_MODE_SILENT); + } else { + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + ToneGenerator tg = new ToneGenerator( + AudioManager.STREAM_NOTIFICATION, + (int)(ToneGenerator.MAX_VOLUME * 0.85)); + if (tg != null) { + tg.startTone(ToneGenerator.TONE_PROP_BEEP); + } + } + } + return; + } else if (action.equals(ActionConstants.ACTION_VIB_SILENT)) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if (am != null && ActivityManagerNative.isSystemReady()) { + if (am.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) { + am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + Vibrator vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if (vib != null) { + vib.vibrate(50); + } + } else if (am.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) { + am.setRingerMode(AudioManager.RINGER_MODE_SILENT); + } else { + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + ToneGenerator tg = new ToneGenerator( + AudioManager.STREAM_NOTIFICATION, + (int)(ToneGenerator.MAX_VOLUME * 0.85)); + if (tg != null) { + tg.startTone(ToneGenerator.TONE_PROP_BEEP); + } + } + } + return; + } else if (action.equals(ActionConstants.ACTION_CAMERA)) { + // ToDo: Send for secure keyguard secure camera intent. + // We need to add support for it first. + Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA, null); + startActivity(context, intent); + return; + } else if (action.equals(ActionConstants.ACTION_MEDIA_PREVIOUS)) { + dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PREVIOUS, context); + return; + } else if (action.equals(ActionConstants.ACTION_MEDIA_NEXT)) { + dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_NEXT, context); + return; + } else if (action.equals(ActionConstants.ACTION_MEDIA_PLAY_PAUSE)) { + dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, context); + return; + } else if (action.equals(ActionConstants.ACTION_WAKE_DEVICE)) { + PowerManager powerManager = + (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (!powerManager.isScreenOn()) { + powerManager.wakeUp(SystemClock.uptimeMillis()); + } + return; + } else { + // we must have a custom uri + Intent intent = null; + try { + intent = Intent.parseUri(action, 0); + } catch (URISyntaxException e) { + Log.e("aosipActions:", "URISyntaxException: [" + action + "]"); + return; + } + startActivity(context, intent); + return; + } + + } + + public static boolean isActionKeyEvent(String action) { + if (action.equals(ActionConstants.ACTION_HOME) + || action.equals(ActionConstants.ACTION_BACK) + || action.equals(ActionConstants.ACTION_SEARCH) + || action.equals(ActionConstants.ACTION_MENU) + || action.equals(ActionConstants.ACTION_MENU_BIG) + || action.equals(ActionConstants.ACTION_NULL)) { + return true; + } + return false; + } + + private static void startActivity(Context context, Intent intent) { + if (intent == null) { + return; + } + try { + WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null /* callback */, null); + } catch (RemoteException e) { + Log.w("Action", "Error dismissing keyguard", e); + } + intent.addFlags( + Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_SINGLE_TOP + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + context.startActivityAsUser(intent, + new UserHandle(UserHandle.USER_CURRENT)); + } + + private static void dispatchMediaKeyWithWakeLock(int keycode, Context context) { + if (ActivityManagerNative.isSystemReady()) { + KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), + SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, keycode, 0); + MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true); + event = KeyEvent.changeAction(event, KeyEvent.ACTION_UP); + MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true); + } + } + + public static void triggerVirtualKeypress(final int keyCode, boolean longpress) { + InputManager im = InputManager.getInstance(); + long now = SystemClock.uptimeMillis(); + int downflags = 0; + int upflags = 0; + if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT + || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT + || keyCode == KeyEvent.KEYCODE_DPAD_UP + || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + downflags = upflags = KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE; + } else { + downflags = upflags = KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY; + } + if (longpress) { + downflags |= KeyEvent.FLAG_LONG_PRESS; + } + + final KeyEvent downEvent = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, + keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + downflags, + InputDevice.SOURCE_KEYBOARD); + im.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + + final KeyEvent upEvent = new KeyEvent(now, now, KeyEvent.ACTION_UP, + keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + upflags, + InputDevice.SOURCE_KEYBOARD); + im.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } +} diff --git a/core/java/com/android/internal/util/aosip/ActionConstants.java b/core/java/com/android/internal/util/aosip/ActionConstants.java new file mode 100644 index 000000000000..0af1e9f383fd --- /dev/null +++ b/core/java/com/android/internal/util/aosip/ActionConstants.java @@ -0,0 +1,102 @@ +/* +* Copyright (C) 2013 SlimRoms Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.android.internal.util.aosip; + +public class ActionConstants { + + // key must fit with the values arrays from Settings to use + // SlimActions.java actions + public static final String ACTION_HOME = "**home**"; + public static final String ACTION_BACK = "**back**"; + public static final String ACTION_SEARCH = "**search**"; + public static final String ACTION_VOICE_SEARCH = "**voice_search**"; + public static final String ACTION_MENU = "**menu**"; + public static final String ACTION_MENU_BIG = "**menu_big**"; + public static final String ACTION_POWER = "**power**"; + public static final String ACTION_NOTIFICATIONS = "**notifications**"; + public static final String ACTION_RECENTS = "**recents**"; + public static final String ACTION_SCREENSHOT = "**screenshot**"; + public static final String ACTION_IME = "**ime**"; + public static final String ACTION_LAST_APP = "**lastapp**"; + public static final String ACTION_KILL = "**kill**"; + public static final String ACTION_ASSIST = "**assist**"; + public static final String ACTION_VIB = "**ring_vib**"; + public static final String ACTION_SILENT = "**ring_silent**"; + public static final String ACTION_VIB_SILENT = "**ring_vib_silent**"; + public static final String ACTION_POWER_MENU = "**power_menu**"; + public static final String ACTION_TORCH = "**torch**"; + public static final String ACTION_EXPANDED_DESKTOP = "**expanded_desktop**"; + public static final String ACTION_THEME_SWITCH = "**theme_switch**"; + public static final String ACTION_KEYGUARD_SEARCH = "**keyguard_search**"; + public static final String ACTION_PIE = "**pie**"; + public static final String ACTION_NAVBAR = "**nav_bar**"; + public static final String ACTION_IME_NAVIGATION_LEFT = "**ime_nav_left**"; + public static final String ACTION_IME_NAVIGATION_RIGHT = "**ime_nav_right**"; + public static final String ACTION_IME_NAVIGATION_UP = "**ime_nav_up**"; + public static final String ACTION_IME_NAVIGATION_DOWN = "**ime_nav_down**"; + public static final String ACTION_CAMERA = "**camera**"; + public static final String ACTION_MEDIA_PREVIOUS = "**media_previous**"; + public static final String ACTION_MEDIA_NEXT = "**media_next**"; + public static final String ACTION_MEDIA_PLAY_PAUSE = "**media_play_pause**"; + public static final String ACTION_WAKE_DEVICE = "**wake_device**"; + + // no action + public static final String ACTION_NULL = "**null**"; + + // this shorcut constant is only used to identify if the user + // selected in settings a custom app...after it is choosed intent uri + // is saved in the ButtonConfig object + public static final String ACTION_APP = "**app**"; + + public static final String ICON_EMPTY = "empty"; + public static final String SYSTEM_ICON_IDENTIFIER = "system_shortcut="; + public static final String ACTION_DELIMITER = "|"; + + public static final String NAVIGATION_CONFIG_DEFAULT = + ACTION_BACK + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY + ACTION_DELIMITER + + ACTION_HOME + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY + ACTION_DELIMITER + + ACTION_RECENTS + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY; + + public static final String NAV_RING_CONFIG_DEFAULT = + ACTION_ASSIST + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY; + + public static final String PIE_SECOND_LAYER_CONFIG_DEFAULT = + ACTION_POWER_MENU + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY + ACTION_DELIMITER + + ACTION_NOTIFICATIONS + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY + ACTION_DELIMITER + + ACTION_SEARCH + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY + ACTION_DELIMITER + + ACTION_SCREENSHOT + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY + ACTION_DELIMITER + + ACTION_IME + ACTION_DELIMITER + + ACTION_NULL + ACTION_DELIMITER + + ICON_EMPTY; + +} diff --git a/core/java/com/android/internal/util/aosip/AppHelper.java b/core/java/com/android/internal/util/aosip/AppHelper.java new file mode 100644 index 000000000000..5713d23fc7e8 --- /dev/null +++ b/core/java/com/android/internal/util/aosip/AppHelper.java @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2013 gzosp Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +package com.android.internal.util.aosip; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.util.Log; + +import java.net.URISyntaxException; + +public class AppHelper { + + private static final String SETTINGS_METADATA_NAME = "com.android.settings"; + + public static String getProperSummary(Context context, PackageManager pm, + Resources settingsResources, String action, String values, String entries) { + + if (pm == null || settingsResources == null || action == null) { + return context.getResources().getString( + com.android.internal.R.string.error_message_title); + } + + if (values != null && entries != null) { + int resIdEntries = -1; + int resIdValues = -1; + + resIdEntries = settingsResources.getIdentifier( + SETTINGS_METADATA_NAME + ":array/" + entries, null, null); + + resIdValues = settingsResources.getIdentifier( + SETTINGS_METADATA_NAME + ":array/" + values, null, null); + + if (resIdEntries > 0 && resIdValues > 0) { + try { + String[] entriesArray = settingsResources.getStringArray(resIdEntries); + String[] valuesArray = settingsResources.getStringArray(resIdValues); + for (int i = 0; i < valuesArray.length; i++) { + if (action.equals(valuesArray[i])) { + return entriesArray[i]; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + return getFriendlyNameForUri(context, pm, action); + } + + public static String getFriendlyActivityName(Context context, + PackageManager pm, Intent intent, boolean labelOnly) { + ActivityInfo ai = intent.resolveActivityInfo(pm, PackageManager.GET_ACTIVITIES); + String friendlyName = null; + + if (ai != null) { + friendlyName = ai.loadLabel(pm).toString(); + if (friendlyName == null && !labelOnly) { + friendlyName = ai.name; + } + } + + if (friendlyName == null || friendlyName.startsWith("#Intent;")) { + return context.getResources().getString( + com.android.internal.R.string.error_message_title); + } + return friendlyName != null || labelOnly ? friendlyName : intent.toUri(0); + } + + public static String getFriendlyShortcutName( + Context context, PackageManager pm, Intent intent) { + String activityName = getFriendlyActivityName(context, pm, intent, true); + String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); + + if (activityName == null || activityName.startsWith("#Intent;")) { + return context.getResources().getString( + com.android.internal.R.string.error_message_title); + } + if (activityName != null && name != null) { + return activityName + ": " + name; + } + return name != null ? name : intent.toUri(0); + } + + public static String getFriendlyNameForUri( + Context context, PackageManager pm, String uri) { + if (uri == null || uri.startsWith("**")) { + return null; + } + + try { + Intent intent = Intent.parseUri(uri, 0); + if (Intent.ACTION_MAIN.equals(intent.getAction())) { + return getFriendlyActivityName(context, pm, intent, false); + } + return getFriendlyShortcutName(context, pm, intent); + } catch (URISyntaxException e) { + } + + return uri; + } + + public static String getShortcutPreferred( + Context context, PackageManager pm, String uri) { + if (uri == null || uri.startsWith("**")) { + return null; + } + try { + Intent intent = Intent.parseUri(uri, 0); + String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); + if (name == null || name.startsWith("#Intent;")) { + return getFriendlyActivityName(context, pm, intent, false); + } + return name; + } catch (URISyntaxException e) { + } + + return uri; + } + +} diff --git a/core/java/com/android/internal/util/aosip/Converter.java b/core/java/com/android/internal/util/aosip/Converter.java new file mode 100644 index 000000000000..505e204823fc --- /dev/null +++ b/core/java/com/android/internal/util/aosip/Converter.java @@ -0,0 +1,30 @@ +/* +* Copyright (C) 2014 SlimRoms Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.android.internal.util.aosip; + +import android.content.Context; + +public class Converter { + + public static int dpToPx(Context context, int dp) { + return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5); + } + + public static int pxToDp(Context context, int px) { + return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5); + } + +} diff --git a/core/java/com/android/internal/util/aosip/DeviceUtils.java b/core/java/com/android/internal/util/aosip/DeviceUtils.java new file mode 100644 index 000000000000..6830206eeff8 --- /dev/null +++ b/core/java/com/android/internal/util/aosip/DeviceUtils.java @@ -0,0 +1,168 @@ +/* +* Copyright (C) 2014 SlimRoms Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.android.internal.util.aosip; + +import android.bluetooth.BluetoothAdapter; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.hardware.display.DisplayManager; +import android.hardware.display.WifiDisplayStatus; +import android.net.ConnectivityManager; +import android.nfc.NfcAdapter; +import android.provider.Settings; +import android.os.Vibrator; +import android.telephony.TelephonyManager; +import android.util.DisplayMetrics; +import android.view.DisplayInfo; +import android.view.WindowManager; +import android.util.Log; + +import com.android.internal.telephony.PhoneConstants; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceUtils { + + private static final String SETTINGS_METADATA_NAME = "com.android.settings"; + + // Device types + private static final int DEVICE_PHONE = 0; + private static final int DEVICE_HYBRID = 1; + private static final int DEVICE_TABLET = 2; + + public static boolean deviceSupportsRemoteDisplay(Context ctx) { + DisplayManager dm = (DisplayManager) ctx.getSystemService(Context.DISPLAY_SERVICE); + return (dm.getWifiDisplayStatus().getFeatureState() + != WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE); + } + + public static boolean deviceSupportsUsbTether(Context context) { + ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + return (cm.getTetherableUsbRegexs().length != 0); + } + + public static boolean deviceSupportsMobileData(Context context) { + ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + return cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); + } + + public static boolean deviceSupportsBluetooth() { + return (BluetoothAdapter.getDefaultAdapter() != null); + } + + public static boolean deviceSupportsNfc(Context context) { + return NfcAdapter.getDefaultAdapter(context) != null; + } + + public static boolean deviceSupportsLte(Context context) { + final TelephonyManager tm = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return (tm.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE); + // || tm.getLteOnGsmMode() != 0; // add back if when we have support on LP for it + } + + public static boolean deviceSupportsGps(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS); + } + + public static boolean adbEnabled(ContentResolver resolver) { + return (Settings.Global.getInt(resolver, Settings.Global.ADB_ENABLED, 0)) == 1; + } + + public static boolean deviceSupportsVibrator(Context ctx) { + Vibrator vibrator = (Vibrator) ctx.getSystemService(Context.VIBRATOR_SERVICE); + return vibrator.hasVibrator(); + } + + public static boolean deviceSupportsTorch(Context context) { + // Need to be adapted to new torch API + return true; + } + + public static FilteredDeviceFeaturesArray filterUnsupportedDeviceFeatures(Context context, + String[] valuesArray, String[] entriesArray) { + if (valuesArray == null || entriesArray == null || context == null) { + return null; + } + List finalEntries = new ArrayList(); + List finalValues = new ArrayList(); + FilteredDeviceFeaturesArray filteredDeviceFeaturesArray = + new FilteredDeviceFeaturesArray(); + + for (int i = 0; i < valuesArray.length; i++) { + if (isSupportedFeature(context, valuesArray[i])) { + finalEntries.add(entriesArray[i]); + finalValues.add(valuesArray[i]); + } + } + filteredDeviceFeaturesArray.entries = + finalEntries.toArray(new String[finalEntries.size()]); + filteredDeviceFeaturesArray.values = + finalValues.toArray(new String[finalValues.size()]); + return filteredDeviceFeaturesArray; + } + + private static boolean isSupportedFeature(Context context, String action) { + if (action.equals(ActionConstants.ACTION_TORCH) + && !deviceSupportsTorch(context) + || action.equals(ActionConstants.ACTION_VIB) + && !deviceSupportsVibrator(context) + || action.equals(ActionConstants.ACTION_VIB_SILENT) + && !deviceSupportsVibrator(context)) { + return false; + } + return true; + } + + public static class FilteredDeviceFeaturesArray { + public String[] entries; + public String[] values; + } + + private static int getScreenType(Context con) { + WindowManager wm = (WindowManager)con.getSystemService(Context.WINDOW_SERVICE); + DisplayInfo outDisplayInfo = new DisplayInfo(); + wm.getDefaultDisplay().getDisplayInfo(outDisplayInfo); + int shortSize = Math.min(outDisplayInfo.logicalHeight, outDisplayInfo.logicalWidth); + int shortSizeDp = + shortSize * DisplayMetrics.DENSITY_DEFAULT / outDisplayInfo.logicalDensityDpi; + if (shortSizeDp < 600) { + return DEVICE_PHONE; + } else if (shortSizeDp < 720) { + return DEVICE_HYBRID; + } else { + return DEVICE_TABLET; + } + } + + public static boolean isPhone(Context con) { + return getScreenType(con) == DEVICE_PHONE; + } + + public static boolean isHybrid(Context con) { + return getScreenType(con) == DEVICE_HYBRID; + } + + public static boolean isTablet(Context con) { + return getScreenType(con) == DEVICE_TABLET; + } +} diff --git a/core/java/com/android/internal/util/aosip/FileUtils.java b/core/java/com/android/internal/util/aosip/FileUtils.java new file mode 100644 index 000000000000..5539b51844d2 --- /dev/null +++ b/core/java/com/android/internal/util/aosip/FileUtils.java @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2016 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. + */ + +package com.android.internal.util.aosip; + +import android.util.Log; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.NullPointerException; +import java.lang.SecurityException; + +public final class FileUtils { + private static final String TAG = "FileUtils"; + + private FileUtils() { + // This class is not supposed to be instantiated + } + + /** + * Reads the first line of text from the given file. + * Reference {@link BufferedReader#readLine()} for clarification on what a line is + * + * @return the read line contents, or null on failure + */ + public static String readOneLine(String fileName) { + String line = null; + BufferedReader reader = null; + + try { + reader = new BufferedReader(new FileReader(fileName), 512); + line = reader.readLine(); + } catch (FileNotFoundException e) { + Log.w(TAG, "No such file " + fileName + " for reading", e); + } catch (IOException e) { + Log.e(TAG, "Could not read from file " + fileName, e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + // Ignored, not much we can do anyway + } + } + + return line; + } + + public static String readLine(String filename) { + if (filename == null) { + return null; + } + BufferedReader br = null; + String line = null; + try { + br = new BufferedReader(new FileReader(filename), 1024); + line = br.readLine(); + } catch (IOException e) { + return null; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + // ignore + } + } + } + return line; + } + + /** + * Writes the given value into the given file + * + * @return true on success, false on failure + */ + public static boolean writeLine(String fileName, String value) { + BufferedWriter writer = null; + + try { + writer = new BufferedWriter(new FileWriter(fileName)); + writer.write(value); + } catch (FileNotFoundException e) { + Log.w(TAG, "No such file " + fileName + " for writing", e); + return false; + } catch (IOException e) { + Log.e(TAG, "Could not write to file " + fileName, e); + return false; + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException e) { + // Ignored, not much we can do anyway + } + } + + return true; + } + + /** + * Write a string value to the specified file. + * @param filename The filename + * @param value The value + */ + public static void writeValue(String filename, String value) { + if (filename == null) { + return; + } + try { + FileOutputStream fos = new FileOutputStream(new File(filename)); + fos.write(value.getBytes()); + fos.flush(); + fos.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Checks whether the given file exists + * + * @return true if exists, false if not + */ + public static boolean fileExists(String fileName) { + final File file = new File(fileName); + return file.exists(); + } + + /** + * Checks whether the given file is readable + * + * @return true if readable, false if not + */ + public static boolean fileReadable(String fileName) { + final File file = new File(fileName); + return file.exists() && file.canRead(); + } + + /** + * Checks whether the given file is writable + * + * @return true if writable, false if not + */ + public static boolean fileWritable(String fileName) { + final File file = new File(fileName); + return file.exists() && file.canWrite(); + } + + /** + * Deletes an existing file + * + * @return true if the delete was successful, false if not + */ + public static boolean delete(String fileName) { + final File file = new File(fileName); + boolean ok = false; + try { + ok = file.delete(); + } catch (SecurityException e) { + Log.w(TAG, "SecurityException trying to delete " + fileName, e); + } + return ok; + } + + /** + * Renames an existing file + * + * @return true if the rename was successful, false if not + */ + public static boolean rename(String srcPath, String dstPath) { + final File srcFile = new File(srcPath); + final File dstFile = new File(dstPath); + boolean ok = false; + try { + ok = srcFile.renameTo(dstFile); + } catch (SecurityException e) { + Log.w(TAG, "SecurityException trying to rename " + srcPath + " to " + dstPath, e); + } catch (NullPointerException e) { + Log.e(TAG, "NullPointerException trying to rename " + srcPath + " to " + dstPath, e); + } + return ok; + } + + public static boolean getFileValueAsBoolean(String filename, boolean defValue) { + String fileValue = readLine(filename); + if(fileValue!=null){ + return (fileValue.equals("0")?false:true); + } + return defValue; + } + + public static String getFileValue(String filename, String defValue) { + String fileValue = readLine(filename); + if(fileValue!=null){ + return fileValue; + } + return defValue; + } +} diff --git a/core/java/com/android/internal/util/aosip/ImageHelper.java b/core/java/com/android/internal/util/aosip/ImageHelper.java new file mode 100644 index 000000000000..ebe82c3bce10 --- /dev/null +++ b/core/java/com/android/internal/util/aosip/ImageHelper.java @@ -0,0 +1,211 @@ +/* +* Copyright (C) 2013 SlimRoms Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.android.internal.util.aosip; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.PorterDuffXfermode; +import android.graphics.PorterDuff.Mode; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Shader.TileMode; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.renderscript.Element; +import android.renderscript.Allocation; +import android.renderscript.ScriptIntrinsicBlur; +import android.renderscript.RenderScript; +import android.util.TypedValue; + +public class ImageHelper { + + public static Bitmap getColoredBitmap(Drawable d, int color) { + if (d == null) { + return null; + } + Bitmap colorBitmap = ((BitmapDrawable) d).getBitmap(); + Bitmap grayscaleBitmap = toGrayscale(colorBitmap); + Paint pp = new Paint(); + pp.setAntiAlias(true); + PorterDuffColorFilter frontFilter = + new PorterDuffColorFilter(color, Mode.MULTIPLY); + pp.setColorFilter(frontFilter); + Canvas cc = new Canvas(grayscaleBitmap); + final Rect rect = new Rect(0, 0, grayscaleBitmap.getWidth(), grayscaleBitmap.getHeight()); + cc.drawBitmap(grayscaleBitmap, rect, rect, pp); + return grayscaleBitmap; + } + + public static Bitmap toGrayscale(Bitmap bmpOriginal) { + int width, height; + height = bmpOriginal.getHeight(); + width = bmpOriginal.getWidth(); + try { + bmpOriginal = RGB565toARGB888(bmpOriginal); + } catch (Exception e) { + e.printStackTrace(); + } + + Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(bmpGrayscale); + Paint paint = new Paint(); + paint.setAntiAlias(true); + ColorMatrix cm = new ColorMatrix(); + final Rect rect = new Rect(0, 0, width, height); + cm.setSaturation(0); + + ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm); + paint.setColorFilter(f); + c.drawBitmap(bmpOriginal, rect, rect, paint); + return bmpGrayscale; + } + + public static Drawable resize(Context context, Drawable image, int size) { + if (image == null || context == null) { + return null; + } + + int newSize = Converter.dpToPx(context, size); + Bitmap bitmap = ((BitmapDrawable) image).getBitmap(); + Bitmap scaledBitmap = Bitmap.createBitmap(newSize, newSize, Config.ARGB_8888); + + float ratioX = newSize / (float) bitmap.getWidth(); + float ratioY = newSize / (float) bitmap.getHeight(); + float middleX = newSize / 2.0f; + float middleY = newSize / 2.0f; + + final Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG); + paint.setAntiAlias(true); + + Matrix scaleMatrix = new Matrix(); + scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); + + Canvas canvas = new Canvas(scaledBitmap); + canvas.setMatrix(scaleMatrix); + canvas.drawBitmap(bitmap, middleX - bitmap.getWidth() / 2, + middleY - bitmap.getHeight() / 2, paint); + return new BitmapDrawable(context.getResources(), scaledBitmap); + } + + public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) { + if (bitmap == null) { + return null; + } + Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), + Config.ARGB_8888); + Canvas canvas = new Canvas(output); + + final int color = 0xff424242; + final Paint paint = new Paint(); + final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); + final RectF rectF = new RectF(rect); + final float roundPx = 24; + paint.setAntiAlias(true); + canvas.drawARGB(0, 0, 0, 0); + paint.setColor(color); + canvas.drawRoundRect(rectF, roundPx, roundPx, paint); + paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); + canvas.drawBitmap(bitmap, rect, rect, paint); + return output; + } + + public static Bitmap getCircleBitmap(Bitmap bitmap) { + if (bitmap == null) { + return null; + } + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + + Bitmap output = Bitmap.createBitmap(width, height, + Config.ARGB_8888); + Canvas canvas = new Canvas(output); + + BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); + final Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setShader(shader); + + canvas.drawCircle(width/2, height/2, width/2, paint); + + return output; + } + + public static Bitmap getBlurredImage(Context context, Bitmap image) { + return getBlurredImage(context, image, 3.5f); + } + + public static Bitmap getBlurredImage(Context context, Bitmap image, float radius) { + try { + image = RGB565toARGB888(image); + } catch (Exception e) { + e.printStackTrace(); + } + + Bitmap bitmap = Bitmap.createBitmap( + image.getWidth(), image.getHeight(), + Bitmap.Config.ARGB_8888); + RenderScript renderScript = RenderScript.create(context); + Allocation blurInput = Allocation.createFromBitmap(renderScript, image); + Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap); + + ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript, + Element.U8_4(renderScript)); + blur.setInput(blurInput); + blur.setRadius(radius); // radius must be 0 < r <= 25 + blur.forEach(blurOutput); + blurOutput.copyTo(bitmap); + renderScript.destroy(); + + return bitmap; + } + public static Bitmap getGrayscaleBlurredImage(Context context, Bitmap image) { + return getGrayscaleBlurredImage(context, image, 3.5f); + } + + public static Bitmap getGrayscaleBlurredImage(Context context, Bitmap image, float radius) { + Bitmap finalImage = Bitmap.createBitmap( + image.getWidth(), image.getHeight(), + Bitmap.Config.ARGB_8888); + finalImage = toGrayscale(getBlurredImage(context, image, radius)); + return finalImage; + } + + private static Bitmap RGB565toARGB888(Bitmap img) throws Exception { + int numPixels = img.getWidth() * img.getHeight(); + int[] pixels = new int[numPixels]; + + //Get JPEG pixels. Each int is the color values for one pixel. + img.getPixels(pixels, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight()); + + //Create a Bitmap of the appropriate format. + Bitmap result = Bitmap.createBitmap(img.getWidth(), img.getHeight(), Bitmap.Config.ARGB_8888); + + //Set RGB pixels. + result.setPixels(pixels, 0, result.getWidth(), 0, 0, result.getWidth(), result.getHeight()); + return result; + } + +} diff --git a/core/java/com/android/internal/util/aosip/TaskUtils.java b/core/java/com/android/internal/util/aosip/TaskUtils.java new file mode 100644 index 000000000000..014a6a9e4758 --- /dev/null +++ b/core/java/com/android/internal/util/aosip/TaskUtils.java @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util.aosip; + +import android.app.Activity; +import android.app.ActivityOptions; +import android.app.ActivityManager; +import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.app.ActivityManagerNative; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.util.Log; +import android.view.WindowManagerGlobal; +import android.view.WindowManager; + +import java.util.List; + +public class TaskUtils { + + private static final String LAUNCHER_PACKAGE = "com.android.launcher3"; + private static final String SYSTEMUI_PACKAGE = "com.android.systemui"; + + public static boolean killActiveTask(Context context, int userId) { + String defaultHomePackage = resolveCurrentLauncherPackageForUser( + context, userId); + boolean targetKilled = false; + final ActivityManager am = (ActivityManager) context + .getSystemService(Activity.ACTIVITY_SERVICE); + List apps = am.getRunningAppProcesses(); + for (RunningAppProcessInfo appInfo : apps) { + int uid = appInfo.uid; + // Make sure it's a foreground user application (not system, + // root, phone, etc.) + if (uid >= Process.FIRST_APPLICATION_UID + && uid <= Process.LAST_APPLICATION_UID + && appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { + if (appInfo.pkgList != null && (appInfo.pkgList.length > 0)) { + for (String pkg : appInfo.pkgList) { + if (!pkg.equals(SYSTEMUI_PACKAGE) && !pkg.equals(defaultHomePackage)) { + am.forceStopPackageAsUser(pkg, userId); + targetKilled = true; + break; + } + } + } else { + Process.killProcess(appInfo.pid); + targetKilled = true; + } + } + if (targetKilled) { + return true; + } + } + return false; + } + + public static void toggleLastApp(Context context, int userId) { + String defaultHomePackage = resolveCurrentLauncherPackageForUser(context, userId); + final ActivityManager am = (ActivityManager) context + .getSystemService(Activity.ACTIVITY_SERVICE); + final List tasks = am.getRecentTasks(5, + ActivityManager.RECENT_IGNORE_UNAVAILABLE); + // lets get enough tasks to find something to switch to + // Note, we'll only get as many as the system currently has - up to 5 + int lastAppId = 0; + Intent lastAppIntent = null; + for (int i = 1; i < tasks.size() && lastAppIntent == null; i++) { + final String packageName = tasks.get(i).baseIntent.getComponent() + .getPackageName(); + if (!packageName.equals(defaultHomePackage) + && !packageName.equals(SYSTEMUI_PACKAGE)) { + final ActivityManager.RecentTaskInfo info = tasks.get(i); + lastAppId = info.id; + lastAppIntent = info.baseIntent; + } + } + if (lastAppId > 0) { + am.moveTaskToFront(lastAppId, + ActivityManager.MOVE_TASK_NO_USER_ACTION); + } else if (lastAppIntent != null) { + // last task is dead, restart it. + lastAppIntent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); + try { + context.startActivityAsUser(lastAppIntent, UserHandle.CURRENT); + } catch (ActivityNotFoundException e) { + } + } + } + + private static String resolveCurrentLauncherPackageForUser(Context context, + int userId) { + final Intent launcherIntent = new Intent(Intent.ACTION_MAIN); + launcherIntent.addCategory(Intent.CATEGORY_HOME); + final PackageManager pm = context.getPackageManager(); + final ResolveInfo launcherInfo = pm.resolveActivityAsUser( + launcherIntent, 0, userId); + if (launcherInfo != null) { + if (launcherInfo.activityInfo != null + && !launcherInfo.activityInfo.packageName.equals("android")) { + return launcherInfo.activityInfo.packageName; + } + } + return LAUNCHER_PACKAGE; + } + + private static int getRunningTask(Context context) { + final ActivityManager am = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + + List tasks = am.getRunningTasks(1); + if (tasks != null && !tasks.isEmpty()) { + return tasks.get(0).id; + } + return -1; + } + + public static ActivityInfo getRunningActivityInfo(Context context) { + final ActivityManager am = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + final PackageManager pm = context.getPackageManager(); + + List tasks = am.getRunningTasks(1); + if (tasks != null && !tasks.isEmpty()) { + ActivityManager.RunningTaskInfo top = tasks.get(0); + try { + return pm.getActivityInfo(top.topActivity, 0); + } catch (PackageManager.NameNotFoundException e) { + } + } + return null; + } + + public static boolean isTaskDocked(Context context) { + if (ActivityManager.supportsMultiWindow(context)) { + try { + return WindowManagerGlobal.getWindowManagerService().getDockedStackSide() != WindowManager.DOCKED_INVALID; + } catch (RemoteException e) { + } + } + return false; + } + + /** + * + */ + public static void dockTopTask(Context context) { + if (ActivityManager.supportsMultiWindow(context) && !isTaskDocked(context)) { + try { + int taskId = getRunningTask(context); + if (taskId != -1) { + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + options.setSplitScreenCreateMode(SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT); + ActivityManagerNative.getDefault().startActivityFromRecents( + taskId, options.toBundle()); + } + } catch (RemoteException e) { + } + } + } +} diff --git a/core/java/com/android/internal/util/aosip/aosipUtils.java b/core/java/com/android/internal/util/aosip/aosipUtils.java new file mode 100644 index 000000000000..4de1fbe7df7c --- /dev/null +++ b/core/java/com/android/internal/util/aosip/aosipUtils.java @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util.aosip; + +import android.app.ActivityManager; +import android.Manifest; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraManager; +import android.hardware.fingerprint.FingerprintManager; +import android.hardware.input.InputManager; +import android.media.AudioManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.BatteryManager; +import android.os.Handler; +import android.os.Looper; +import android.os.PowerManager; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.os.SystemClock; +import android.os.SystemProperties; +import android.os.UserHandle; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.os.Vibrator; +import android.view.InputDevice; +import android.view.IWindowManager; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.WindowManagerGlobal; + +import com.android.internal.R; +import com.android.internal.statusbar.IStatusBarService; + +import java.util.Arrays; +import java.util.Locale; + +import static android.content.Context.NOTIFICATION_SERVICE; +import static android.content.Context.VIBRATOR_SERVICE; + +public class aosipUtils { + + public static final String INTENT_SCREENSHOT = "action_handler_screenshot"; + public static final String INTENT_REGION_SCREENSHOT = "action_handler_region_screenshot"; + + private static IStatusBarService mStatusBarService = null; + + private static IStatusBarService getStatusBarService() { + synchronized (aosipUtils.class) { + if (mStatusBarService == null) { + mStatusBarService = IStatusBarService.Stub.asInterface( + ServiceManager.getService("statusbar")); + } + return mStatusBarService; + } + } + + public static boolean isPackageInstalled(Context context, String pkg, boolean ignoreState) { + if (pkg != null) { + try { + PackageInfo pi = context.getPackageManager().getPackageInfo(pkg, 0); + if (!pi.applicationInfo.enabled && !ignoreState) { + return false; + } + } catch (NameNotFoundException e) { + return false; + } + } + + return true; + } + public static boolean isPackageInstalled(Context context, String pkg) { + return isPackageInstalled(context, pkg, true); + } + 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 e) { + // Ignore + } + return false; + } + public static void takeScreenshot(boolean full) { + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); + try { + wm.sendCustomAction(new Intent(full? INTENT_SCREENSHOT : INTENT_REGION_SCREENSHOT)); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + // Check to see if device is WiFi only + public static boolean isWifiOnly(Context context) { + ConnectivityManager cm = (ConnectivityManager)context.getSystemService( + Context.CONNECTIVITY_SERVICE); + return (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false); + } + // Check to see if device supports the Fingerprint scanner + public static boolean hasFingerprintSupport(Context context) { + FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); + return context.getApplicationContext().checkSelfPermission(Manifest.permission.USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED && + (fingerprintManager != null && fingerprintManager.isHardwareDetected()); + } + // Check to see if device not only supports the Fingerprint scanner but also if is enrolled + public static boolean hasFingerprintEnrolled(Context context) { + FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); + return context.getApplicationContext().checkSelfPermission(Manifest.permission.USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED && + (fingerprintManager != null && fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()); + } + // Check to see if device has a camera + public static boolean hasCamera(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); + } + // Check to see if device supports NFC + public static boolean hasNFC(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC); + } + // Check to see if device supports Wifi + public static boolean hasWiFi(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI); + } + // Check to see if device supports Bluetooth + public static boolean hasBluetooth(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); + } + // Check to see if device supports an alterative ambient display package + public static boolean hasAltAmbientDisplay(Context context) { + return context.getResources().getBoolean(com.android.internal.R.bool.config_alt_ambient_display); + } + // Check to see if device supports A/B (seamless) system updates + public static boolean isABdevice(Context context) { + return SystemProperties.getBoolean("ro.build.ab_update", false); + } + // Check for Chinese language + public static boolean isChineseLanguage() { + return Resources.getSystem().getConfiguration().locale.getLanguage().startsWith( + Locale.CHINESE.getLanguage()); + } + // Method to turn off the screen + public static void switchScreenOff(Context ctx) { + PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); + if (pm!= null && pm.isScreenOn()) { + pm.goToSleep(SystemClock.uptimeMillis()); + } + } + // Screen on + public static void switchScreenOn(Context context) { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (pm == null) return; + pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK"); + } + public static void takeScreenrecord(int mode) { + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); + try { + wm.screenRecordAction(mode); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + public static boolean deviceHasFlashlight(Context ctx) { + return ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); + } + public static void toggleVolumePanel(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + am.adjustVolume(AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI); + } + // Toggle flashlight + public static void toggleCameraFlash() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.toggleCameraFlash(); + } catch (RemoteException e) { + // do nothing. + } + } + } + public static void toggleCameraFlashState(boolean enable) { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.toggleCameraFlashState(enable); + } catch (RemoteException e) { + // do nothing.s + } + } + } + // Cycle ringer modes + public static void toggleRingerModes (Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + Vibrator vibrator = (Vibrator) context.getSystemService(VIBRATOR_SERVICE); + + switch (am.getRingerMode()) { + case AudioManager.RINGER_MODE_NORMAL: + if (vibrator.hasVibrator()) { + am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + } + break; + case AudioManager.RINGER_MODE_VIBRATE: + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + notificationManager.setInterruptionFilter( + NotificationManager.INTERRUPTION_FILTER_PRIORITY); + break; + case AudioManager.RINGER_MODE_SILENT: + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + break; + } + } + public static void sendKeycode(int keycode, Handler h) { + long when = SystemClock.uptimeMillis(); + final KeyEvent evDown = new KeyEvent(when, when, KeyEvent.ACTION_DOWN, keycode, 0, + 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, + InputDevice.SOURCE_KEYBOARD); + final KeyEvent evUp = KeyEvent.changeAction(evDown, KeyEvent.ACTION_UP); + h.post(new Runnable() { + @Override + public void run() { + InputManager.getInstance().injectInputEvent(evDown, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + }); + h.postDelayed(new Runnable() { + @Override + public void run() { + InputManager.getInstance().injectInputEvent(evUp, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + }, 20); + } + public static void sendKeycode(int keycode) { + long when = SystemClock.uptimeMillis(); + final KeyEvent evDown = new KeyEvent(when, when, KeyEvent.ACTION_DOWN, keycode, 0, + 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, + InputDevice.SOURCE_KEYBOARD); + final KeyEvent evUp = KeyEvent.changeAction(evDown, KeyEvent.ACTION_UP); + final Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + InputManager.getInstance().injectInputEvent(evDown, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + }); + handler.postDelayed(new Runnable() { + @Override + public void run() { + InputManager.getInstance().injectInputEvent(evUp, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + }, 20); + } + public static void goToSleep(Context context) { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if(pm != null) { + pm.goToSleep(SystemClock.uptimeMillis()); + } + } + public static void moveKbCursor(int action, boolean right) { + int code = right ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT; + long downTime = System.currentTimeMillis(); + long when = downTime; + final KeyEvent ev = new KeyEvent(downTime, when, action, code, 0, + 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + (KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE), + InputDevice.SOURCE_KEYBOARD); + InputManager.getInstance().injectInputEvent(ev, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + // Clear notifications + public static void clearAllNotifications() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.onClearAllNotifications(ActivityManager.getCurrentUser()); + } catch (RemoteException e) { + // do nothing. + } + } + } + // Toggle notifications panel + public static void toggleNotifications() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.togglePanel(); + } catch (RemoteException e) { + // do nothing. + } + } + } + // Toggle qs panel + public static void toggleQsPanel() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.toggleSettingsPanel(); + } catch (RemoteException e) { + // do nothing. + } + } + } + // Method to detect battery temperature + public static String batteryTemperature(Context context, Boolean ForC) { + Intent intent = context.registerReceiver(null, new IntentFilter( + Intent.ACTION_BATTERY_CHANGED)); + float temp = ((float) (intent != null ? intent.getIntExtra( + BatteryManager.EXTRA_TEMPERATURE, 0) : 0)) / 10; + // Round up to nearest number + int c = (int) ((temp) + 0.5f); + float n = temp + 0.5f; + // Use boolean to determine celsius or fahrenheit + return String.valueOf((n - c) % 2 == 0 ? (int) temp : + ForC ? c * 9/5 + 32:c); + } + // Method to detect countries that use Fahrenheit + public static boolean mccCheck(Context context) { + // MCC's belonging to countries that use Fahrenheit + String[] mcc = {"364", "552", "702", "346", "550", "376", "330", + "310", "311", "312", "551"}; + + TelephonyManager tel = (TelephonyManager) context.getSystemService( + Context.TELEPHONY_SERVICE); + String networkOperator = tel.getNetworkOperator(); + + // Check the array to determine celsius or fahrenheit. + // Default to celsius if can't access MCC + return !TextUtils.isEmpty(networkOperator) && Arrays.asList(mcc).contains( + networkOperator.substring(0, /*Filter only 3 digits*/ 3)); + } + // Method to detect if device is plugged in (wired or wireless) + public static boolean isPlugged(Context context) { + boolean isPlugged; + Intent intent = context.registerReceiver(null, new IntentFilter( + Intent.ACTION_BATTERY_CHANGED)); + int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); + isPlugged = plugged == + BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB; + isPlugged = isPlugged || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS; + return isPlugged; + } + // Check if device has a notch + public static boolean hasNotch(Context context) { + int result = 0; + int resid; + int resourceId = context.getResources().getIdentifier( + "status_bar_height", "dimen", "android"); + resid = context.getResources().getIdentifier("config_fillMainBuiltInDisplayCutout", + "bool", "android"); + if (resid > 0) { + return context.getResources().getBoolean(resid); + } + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); + float px = 24 * (metrics.densityDpi / 160f); + return result > Math.round(px); + } +} diff --git a/core/java/com/android/internal/util/custom/recorder/InternalAudioRecorder.java b/core/java/com/android/internal/util/custom/recorder/InternalAudioRecorder.java new file mode 100644 index 000000000000..adf393956dc2 --- /dev/null +++ b/core/java/com/android/internal/util/custom/recorder/InternalAudioRecorder.java @@ -0,0 +1,24 @@ +/* +* Copyright (C) 2017 The Pixel Experience Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.android.internal.util.custom.recorder; + +import android.content.Context; + +public class InternalAudioRecorder { + public static boolean isSupported(Context context) { + return context.getResources().getBoolean(com.android.internal.R.bool.config_hasInternalAudioRecordingSupport); + } +} diff --git a/core/java/com/android/internal/util/custom/thermal/ThermalController.java b/core/java/com/android/internal/util/custom/thermal/ThermalController.java new file mode 100644 index 000000000000..5ff33b801ac6 --- /dev/null +++ b/core/java/com/android/internal/util/custom/thermal/ThermalController.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 The PixelExperience Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.android.internal.util.custom.thermal; + +import android.content.ContentValues; +import android.content.Context; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.content.Intent; +import android.os.UserHandle; + +public class ThermalController { + + public static final String SERVICE_PACKAGE = "org.pixelexperience.thermalcontroller"; + public static final String ACTIVE_PACKAGE_CHANGED_ACTION = "android.intent.action.ACTIVE_PACKAGE_CHANGED"; + public static final String ACTIVE_PACKAGE_CHANGED_EXTRA = "package_name"; + public static final String AUTHORITY = "org.pixelexperience.thermalcontroller"; + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/preferences"); + public static final String COLUMN_PROFILE = "profile"; + public static final String[] PROJECTION_DEFAULT = new String[]{COLUMN_PROFILE}; + + public static boolean isAvailable(Context context) { + final PackageManager pm = context.getPackageManager(); + try { + pm.getPackageInfo(SERVICE_PACKAGE, PackageManager.GET_ACTIVITIES); + int enabled = pm.getApplicationEnabledSetting(SERVICE_PACKAGE); + return enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED && + enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + public static void setProfile(String packageName, int profile, Context context) { + ContentValues values = new ContentValues(); + values.put(COLUMN_PROFILE, profile); + context.getContentResolver().insert(Uri.parse(CONTENT_URI + "/" + packageName), values); + } + + public static int getProfile(String packageName, Context context) { + Cursor c = context.getContentResolver().query(Uri.parse(CONTENT_URI + "/" + packageName), PROJECTION_DEFAULT, + null, null, null); + if (c != null) { + try { + int count = c.getCount(); + if (count > 0) { + for (int i = 0; i < count; i++) { + c.moveToPosition(i); + if (i == 0) { + return c.getInt(0); + } + } + } + } finally { + c.close(); + } + } + return 0; + } + + public static void sendActivePackageChangedBroadcast(String packageName, Context context) { + Intent intent = new Intent(ACTIVE_PACKAGE_CHANGED_ACTION); + intent.putExtra(ACTIVE_PACKAGE_CHANGED_EXTRA, packageName); + intent.setFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + context.sendBroadcastAsUser(intent, UserHandle.SYSTEM); + } +} diff --git a/core/java/com/android/internal/util/custom/weather/WeatherClient.java b/core/java/com/android/internal/util/custom/weather/WeatherClient.java new file mode 100644 index 000000000000..a4fe965f11ad --- /dev/null +++ b/core/java/com/android/internal/util/custom/weather/WeatherClient.java @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2018 The OmniROM Project + * The PixelExperience Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.android.internal.util.custom.weather; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Process; +import android.os.SystemProperties; +import android.util.Log; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import com.android.internal.R; + +public class WeatherClient { + + public static final String SERVICE_PACKAGE = "org.pixelexperience.weather.client"; + public static final Uri WEATHER_URI = Uri.parse("content://org.pixelexperience.weather.client.provider/weather"); + public static final int WEATHER_UPDATE_SUCCESS = 0; // Success + public static final int WEATHER_UPDATE_RUNNING = 1; // Update running + public static final int WEATHER_UPDATE_ERROR = 2; // Error + private static final String TAG = "WeatherClient"; + private static final boolean DEBUG = false; + private static final String COLUMN_STATUS = "status"; + private static final String COLUMN_CONDITIONS = "conditions"; + private static final String COLUMN_TEMPERATURE_METRIC = "temperatureMetric"; + private static final String COLUMN_TEMPERATURE_IMPERIAL = "temperatureImperial"; + private static final String[] PROJECTION_DEFAULT_WEATHER = new String[]{ + COLUMN_STATUS, + COLUMN_CONDITIONS, + COLUMN_TEMPERATURE_METRIC, + COLUMN_TEMPERATURE_IMPERIAL + }; + + private boolean mBootAndUnlockDone; + + private static final int WEATHER_UPDATE_INTERVAL = 60 * 20 * 1000; // 20 minutes + private String updateIntentAction; + private PendingIntent pendingWeatherUpdate; + private WeatherInfo mWeatherInfo = new WeatherInfo(); + private Context mContext; + private List mObserver; + private boolean isRunning; + private boolean isScreenOn = true; + private long lastUpdated; + private long scheduledAlarmTime = 0; + private AlarmManager alarmManager; + private BroadcastReceiver weatherReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent == null) { + return; + } + if (DEBUG) Log.d(TAG, "Received intent: " + intent.getAction()); + if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { + onScreenOff(); + } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) { + onScreenOn(); + } else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { + mBootAndUnlockDone = true; + updateWeatherAndNotify(false); + } else if (updateIntentAction.equals(intent.getAction())) { + updateWeatherAndNotify(false); + } else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction()) + || Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { + updateWeatherAndNotify(true); + } + } + }; + + public WeatherClient(Context context) { + mContext = context; + updateIntentAction = "updateIntentAction_" + Integer.toString(getRandomInt()); + pendingWeatherUpdate = PendingIntent.getBroadcast(mContext, getRandomInt(), new Intent(updateIntentAction), 0); + mObserver = new ArrayList<>(); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_BOOT_COMPLETED); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(updateIntentAction); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + mContext.registerReceiver(weatherReceiver, filter); + // check if this is a SystemUI restart and boot was already completed + if ("1".equals(SystemProperties.get("sys.boot_completed"))) { + mBootAndUnlockDone = true; + } + } + + private int getRandomInt() { + Random r = new Random(); + return r.nextInt((20000000 - 10000000) + 1) + 10000000; + } + + private void updateWeatherAndNotify(boolean forceResetSchedule) { + if (!mBootAndUnlockDone) return; + + if (isRunning) { + if (forceResetSchedule) resetScheduledAlarm(); + return; + } + isRunning = true; + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + updateWeatherData(); + for (WeatherObserver observer : mObserver) { + try { + observer.onWeatherUpdated(mWeatherInfo); + } catch (Exception ignored) { + } + } + lastUpdated = System.currentTimeMillis(); + resetScheduledAlarm(); + } + }); + thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND); + thread.start(); + } + + private boolean needsUpdate() { + boolean lastUpdatedExpired = System.currentTimeMillis() - lastUpdated > WEATHER_UPDATE_INTERVAL; + return mWeatherInfo.getStatus() != WEATHER_UPDATE_SUCCESS || lastUpdatedExpired; + } + + private void onScreenOn() { + if (!mBootAndUnlockDone || isScreenOn){ + return; + } + if (DEBUG) Log.d(TAG, "onScreenOn"); + isScreenOn = true; + if (!isRunning) { + if (needsUpdate()) { + if (DEBUG) Log.d(TAG, "Needs update, triggering updateWeatherAndNotify"); + updateWeatherAndNotify(false); + } else { + if (DEBUG) Log.d(TAG, "Scheduling update"); + scheduleWeatherUpdateAlarm(); + } + } + } + + private void onScreenOff() { + if (DEBUG) Log.d(TAG, "onScreenOff"); + isScreenOn = false; + cancelWeatherUpdateAlarm(); + } + + private void resetScheduledAlarm(){ + scheduledAlarmTime = 0; + scheduleWeatherUpdateAlarm(); + } + + private void scheduleWeatherUpdateAlarm() { + if (!isScreenOn) { + return; + } + if (System.currentTimeMillis() >= scheduledAlarmTime){ + scheduledAlarmTime = System.currentTimeMillis() + WEATHER_UPDATE_INTERVAL; + } + alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); + alarmManager.cancel(pendingWeatherUpdate); + alarmManager.setExact(AlarmManager.RTC_WAKEUP, scheduledAlarmTime, pendingWeatherUpdate); + if (DEBUG) Log.d(TAG, "Update scheduled"); + } + + private void cancelWeatherUpdateAlarm() { + alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); + alarmManager.cancel(pendingWeatherUpdate); + if (DEBUG) Log.d(TAG, "Update scheduling canceled"); + } + + private void updateWeatherData() { + isRunning = true; + Cursor c = mContext.getContentResolver().query(WEATHER_URI, PROJECTION_DEFAULT_WEATHER, + null, null, null); + if (c != null) { + try { + int count = c.getCount(); + if (count > 0) { + for (int i = 0; i < count; i++) { + c.moveToPosition(i); + if (i == 0) { + mWeatherInfo.status = c.getInt(0); + mWeatherInfo.conditions = c.getString(1); + mWeatherInfo.temperatureMetric = c.getInt(2); + mWeatherInfo.temperatureImperial = c.getInt(3); + } + } + } + } finally { + c.close(); + } + } else { + mWeatherInfo.status = WEATHER_UPDATE_ERROR; + } + + if (DEBUG) Log.d(TAG, mWeatherInfo.toString()); + isRunning = false; + } + + public void addObserver(final WeatherObserver observer, boolean withQuery) { + mObserver.add(observer); + if (withQuery) { + if (isRunning) { + return; + } + isRunning = true; + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + updateWeatherData(); + try { + observer.onWeatherUpdated(mWeatherInfo); + } catch (Exception ignored) { + } + } + }); + thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND); + thread.start(); + } + } + + public void removeObserver(WeatherObserver observer) { + mObserver.remove(observer); + } + + public void destroy(){ + mContext.unregisterReceiver(weatherReceiver); + mObserver = new ArrayList<>(); + } + + public interface WeatherObserver { + void onWeatherUpdated(WeatherInfo info); + } + + public class WeatherInfo { + + int status = WEATHER_UPDATE_ERROR; + String conditions = ""; + int temperatureMetric = 0; + int temperatureImperial = 0; + final Map conditionsToDrawableMap = new HashMap<>(); + + public WeatherInfo() { + conditionsToDrawableMap.put("partly-cloudy", R.drawable.weather_partly_cloudy); + conditionsToDrawableMap.put("partly-cloudy-night", R.drawable.weather_partly_cloudy_night); + conditionsToDrawableMap.put("mostly-cloudy", R.drawable.weather_mostly_cloudy); + conditionsToDrawableMap.put("mostly-cloudy-night", R.drawable.weather_mostly_cloudy_night); + conditionsToDrawableMap.put("cloudy", R.drawable.weather_cloudy); + conditionsToDrawableMap.put("clear-night", R.drawable.weather_clear_night); + conditionsToDrawableMap.put("mostly-clear-night", R.drawable.weather_mostly_clear_night); + conditionsToDrawableMap.put("sunny", R.drawable.weather_sunny); + conditionsToDrawableMap.put("mostly-sunny", R.drawable.weather_mostly_sunny); + conditionsToDrawableMap.put("scattered-showers", R.drawable.weather_scattered_showers); + conditionsToDrawableMap.put("scattered-showers-night", R.drawable.weather_scattered_showers_night); + conditionsToDrawableMap.put("rain", R.drawable.weather_rain); + conditionsToDrawableMap.put("windy", R.drawable.weather_windy); + conditionsToDrawableMap.put("snow", R.drawable.weather_snow); + conditionsToDrawableMap.put("scattered-thunderstorms", R.drawable.weather_isolated_scattered_thunderstorms); + conditionsToDrawableMap.put("scattered-thunderstorms-night", R.drawable.weather_isolated_scattered_thunderstorms_night); + conditionsToDrawableMap.put("isolated-thunderstorms", R.drawable.weather_isolated_scattered_thunderstorms); + conditionsToDrawableMap.put("isolated-thunderstorms-night", R.drawable.weather_isolated_scattered_thunderstorms_night); + conditionsToDrawableMap.put("thunderstorms", R.drawable.weather_thunderstorms); + conditionsToDrawableMap.put("foggy", R.drawable.weather_foggy); + } + + public int getTemperature(boolean metric) { + return metric ? this.temperatureMetric : this.temperatureImperial; + } + + public int getStatus() { + return this.status; + } + + public String getConditions() { + return this.conditions; + } + + public int getWeatherConditionImage() { + if (conditionsToDrawableMap.containsKey(conditions)) + return conditionsToDrawableMap.get(conditions); + return 0; + } + + @Override + public String toString() { + return "WeatherInfo: " + + "status=" + getStatus() + "," + + "conditions=" + getConditions() + "," + + "temperatureMetric=" + getTemperature(true) + "," + + "temperatureImperial=" + getTemperature(false); + } + } +} diff --git a/core/java/com/android/internal/utils/ActionConstants.java b/core/java/com/android/internal/utils/ActionConstants.java new file mode 100644 index 000000000000..25980551eaf6 --- /dev/null +++ b/core/java/com/android/internal/utils/ActionConstants.java @@ -0,0 +1,649 @@ +/* + * Copyright (C) 2015 TeamEos project + * Author Randall Rushing aka bigrushdog, randall.rushing@gmail.com + * + * 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. + * + * ActionConstants.java: A helper class to assist Config.java with loading + * and assigning default feature configurations. Nested classes implement + * the static interface Defaults, which allows Settings and Config.java + * to handle configurations in a non-implementation specific way, allowing + * for more generalized code structures. + * + * Of strong importance is the ConfigMap pojo class. Current settings use + * a ActionPreference which sets a single action. Therefore, we must have a + * way to map individual actions to their associated buttons. ActionPreference + * key MUST match the tag associated with the target ConfigMap. + * + */ + +package com.android.internal.utils; + +import java.util.HashMap; +import java.util.Map; + +import com.android.internal.utils.ActionHandler.SystemAction; +import com.android.internal.utils.Config.ActionConfig; + +import android.content.Context; +import android.content.res.Resources; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; +import android.util.TypedValue; + +public class ActionConstants { + public static interface Defaults { + public int getConfigType(); + public String getUri(); + public String getDefaultConfig(); + public int getMaxButtons(); + public Map getActionMap(); + public Bundle getConfigs(Context context); + } + + public static final String ACTION_DELIMITER = "|"; + public static final String EMPTY = "empty"; + public static final int SMARTBAR = 1; + public static final int HWKEYS = 2; + public static final int FLING = 3; + public static final int PIE_PRIMARY = 4; + public static final int PIE_SECONDARY = 5; + + private static final Smartbar smartbar = new Smartbar(); + private static final Hwkeys hwkeys = new Hwkeys(); + private static final Fling fling = new Fling(); + private static final PiePrimary pie_primary = new PiePrimary(); + private static final PieSecond pie_second = new PieSecond(); + + public static Defaults getDefaults(int type) { + if (type == SMARTBAR) { + return smartbar; + } else if (type == HWKEYS) { + return hwkeys; + } else if (type == FLING) { + return fling; + } else if (type == PIE_PRIMARY){ + return pie_primary; + } else if (type == PIE_SECONDARY) { + return pie_second; + } else { + return null; + } + } + + public static String dl(String s) { + return s + ACTION_DELIMITER; + } + + public static class Smartbar implements Defaults { + public static final int SMARTBAR_MAX_BUTTONS = 10; + public static final String SMARTBAR_DEF_BUTTONS = "3"; + public static final String BUTTON1_TAG = "smartbar_button_1"; + public static final String BUTTON2_TAG = "smartbar_button_2"; + public static final String BUTTON3_TAG = "smartbar_button_3"; + public static final String BUTTON4_TAG = "smartbar_button_4"; + public static final String BUTTON5_TAG = "smartbar_button_5"; + public static final String BUTTON6_TAG = "smartbar_button_6"; + public static final String BUTTON7_TAG = "smartbar_button_7"; + + public static final String SMARTBAR_CONFIG_DEFAULT = + dl(SMARTBAR_DEF_BUTTONS) // default number of ButtonConfig + + dl(BUTTON1_TAG) // button tag + + dl(SystemAction.Back.mAction) + dl(SystemAction.Back.mLabelRes) + dl(EMPTY) // single tap (PRIMARY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // long press (SECOND) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // double tap (THIRD) + + + dl(BUTTON2_TAG) + + dl(SystemAction.Home.mAction) + dl(SystemAction.Home.mLabelRes) + dl(EMPTY) + + dl(SystemAction.GoogleNowOnTap.mAction) + dl(SystemAction.GoogleNowOnTap.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(BUTTON3_TAG) + + dl(SystemAction.Overview.mAction) + dl(SystemAction.Overview.mLabelRes) + dl(EMPTY) + + dl(SystemAction.SplitScreen.mAction) + dl(SystemAction.SplitScreen.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + EMPTY; +/* + + dl(BUTTON4_TAG) + + dl(SystemAction.ExpandedDesktop.mAction) + dl(SystemAction.ExpandedDesktop.mLabelRes) + dl(EMPTY) + + dl(SystemAction.Flashlight.mAction) + dl(SystemAction.Flashlight.mLabelRes) + dl(EMPTY) + + dl(SystemAction.PowerMenu.mAction) + dl(SystemAction.PowerMenu.mLabelRes) + dl(EMPTY) + + + dl(BUTTON5_TAG) + + dl(SystemAction.Screenrecord.mAction) + dl(SystemAction.Screenrecord.mLabelRes) + dl(EMPTY) + + dl(SystemAction.KillApp.mAction) + dl(SystemAction.KillApp.mLabelRes) + dl(EMPTY) + + dl(SystemAction.ScreenOff.mAction) + dl(SystemAction.ScreenOff.mLabelRes) + EMPTY; +*/ + @Override + public String getUri() { + return "smartbar_button_config"; + } + + @Override + public String getDefaultConfig() { + return SMARTBAR_CONFIG_DEFAULT; + } + + @Override + public int getMaxButtons() { + return SMARTBAR_MAX_BUTTONS; + } + + @Override + public int getConfigType() { + return SMARTBAR; + } + + @Override + public Map getActionMap() { + return null; + } + + @Override + public Bundle getConfigs(Context context) { + // TODO Auto-generated method stub + return null; + } + } + + public static class Hwkeys implements Defaults { + public static final int HWKEY_MAX_BUTTONS = 7; + public static final String HWKEY_DEF_BUTTONS = "5"; + public static final String BACK_BUTTON_TAG = "hwkeys_button_back"; + public static final String HOME_BUTTON_TAG = "hwkeys_button_home"; + public static final String OVERVIEW_BUTTON_TAG = "hwkeys_button_overview"; + public static final String MENU_BUTTON_TAG = "hwkeys_button_menu"; + public static final String ASSIST_BUTTON_TAG = "hwkeys_button_assist"; + public static final String EXTRA1_BUTTON_TAG = "hwkeys_button_camera"; + public static final String EXTRA2_BUTTON_TAG = "hwkeys_button_extra"; + + public static final String BACK_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_back_single_tap"; + public static final String HOME_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_home_single_tap"; + public static final String OVERVIEW_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_overview_single_tap"; + public static final String MENU_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_menu_single_tap"; + public static final String ASSIST_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_assist_single_tap"; + + public static final String BACK_BUTTON_LONG_PRESS_TAG = "hwkeys_button_back_long_press"; + public static final String HOME_BUTTON_LONG_PRESS_TAG = "hwkeys_button_home_long_press"; + public static final String OVERVIEW_BUTTON_LONG_PRESS_TAG = "hwkeys_button_overview_long_press"; + public static final String MENU_BUTTON_LONG_PRESS_TAG = "hwkeys_button_menu_long_press"; + public static final String ASSIST_BUTTON_LONG_PRESS_TAG = "hwkeys_button_assist_long_press"; + + public static final String BACK_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_back_double_tap"; + public static final String HOME_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_home_double_tap"; + public static final String OVERVIEW_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_overview_double_tap"; + public static final String MENU_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_menu_double_tap"; + public static final String ASSIST_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_assist_double_tap"; + + private static final Map configMap = new HashMap(); + + static { + configMap.put(BACK_BUTTON_SINGLE_TAP_TAG, new ConfigMap(0, ActionConfig.PRIMARY)); + configMap.put(HOME_BUTTON_SINGLE_TAP_TAG, new ConfigMap(1, ActionConfig.PRIMARY)); + configMap.put(OVERVIEW_BUTTON_SINGLE_TAP_TAG, new ConfigMap(2, ActionConfig.PRIMARY)); + configMap.put(MENU_BUTTON_SINGLE_TAP_TAG, new ConfigMap(3, ActionConfig.PRIMARY)); + configMap.put(ASSIST_BUTTON_SINGLE_TAP_TAG, new ConfigMap(4, ActionConfig.PRIMARY)); + configMap.put(BACK_BUTTON_LONG_PRESS_TAG, new ConfigMap(0, ActionConfig.SECOND)); + configMap.put(HOME_BUTTON_LONG_PRESS_TAG, new ConfigMap(1, ActionConfig.SECOND)); + configMap.put(OVERVIEW_BUTTON_LONG_PRESS_TAG, new ConfigMap(2, ActionConfig.SECOND)); + configMap.put(MENU_BUTTON_LONG_PRESS_TAG, new ConfigMap(3, ActionConfig.SECOND)); + configMap.put(ASSIST_BUTTON_LONG_PRESS_TAG, new ConfigMap(4, ActionConfig.SECOND)); + configMap.put(BACK_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(0, ActionConfig.THIRD)); + configMap.put(HOME_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(1, ActionConfig.THIRD)); + configMap.put(OVERVIEW_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(2, ActionConfig.THIRD)); + configMap.put(MENU_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(3, ActionConfig.THIRD)); + configMap.put(ASSIST_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(4, ActionConfig.THIRD)); + } + + public static final String HWKEYS_CONFIG_DEFAULT = + dl(HWKEY_DEF_BUTTONS) + + dl(BACK_BUTTON_TAG) + + dl(SystemAction.Back.mAction) + dl(SystemAction.Back.mLabelRes) + dl(EMPTY) // single tap (PRIMARY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // long press (SECOND) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // double tap (THIRD) + + + dl(HOME_BUTTON_TAG) + + dl(SystemAction.Home.mAction) + dl(SystemAction.Home.mLabelRes) + dl(EMPTY) + + dl(SystemAction.Assistant.mAction) + dl(SystemAction.Assistant.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(OVERVIEW_BUTTON_TAG) + + dl(SystemAction.Overview.mAction) + dl(SystemAction.Overview.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(MENU_BUTTON_TAG) + + dl(SystemAction.Menu.mAction) + dl(SystemAction.Menu.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(ASSIST_BUTTON_TAG) + + dl(SystemAction.Assistant.mAction) + dl(SystemAction.Assistant.mLabelRes) + dl(EMPTY) + + dl(SystemAction.VoiceSearch.mAction) + dl(SystemAction.VoiceSearch.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + EMPTY; + + @Override + public int getConfigType() { + return HWKEYS; + } + + @Override + public String getUri() { + //return Settings.System.HWKEY_BUTTON_ACTIONS; + return "hwkey_config"; + } + + @Override + public String getDefaultConfig() { + return HWKEYS_CONFIG_DEFAULT; + } + + @Override + public int getMaxButtons() { + return HWKEY_MAX_BUTTONS; + } + + @Override + public Map getActionMap() { + return configMap; + } + + @Override + public Bundle getConfigs(Context context) { + // TODO Auto-generated method stub + return null; + } + } + + public static class Fling implements Defaults { + public static final int FLING_MAX_BUTTONS = 10; + public static final String FLING_DEF_BUTTONS = "5"; + + public static final String RIGHT_TAP_TAG = "fling_right_taps"; + public static final String LEFT_TAP_TAG = "fling_left_taps"; + public static final String RIGHT_FLING_TAG = "fling_right"; + public static final String LEFT_FLING = "fling_left"; + public static final String UP_FLING = "fling_up"; + + public static final String SINGLE_LEFT_TAP_TAG = "single_left_tap"; + public static final String SINGLE_RIGHT_TAP_TAG = "single_right_tap"; + public static final String DOUBLE_LEFT_TAP_TAG = "double_left_tap"; + public static final String DOUBLE_RIGHT_TAP_TAG = "double_right_tap"; + public static final String LONG_LEFT_PRESS_TAG = "long_left_press"; + public static final String LONG_RIGHT_PRESS_TAG = "long_right_press"; + public static final String FLING_SHORT_LEFT_TAG = "fling_short_left"; + public static final String FLING_SHORT_RIGHT_TAG = "fling_short_right"; + public static final String FLING_LONG_LEFT_TAG = "fling_long_left"; + public static final String FLING_LONG_RIGHT_TAG = "fling_long_right"; + public static final String FLING_RIGHT_UP_TAG = "fling_right_up"; + public static final String FLING_LEFT_UP_TAG = "fling_left_up"; + public static final String CONFIG_fling_touchslop_increase_factor = "config_fling_touchslop_increase_factor"; + public static final String CONFIG_FlingLongSwipePortraitLeft = "config_FlingLongSwipePortraitLeft"; + public static final String CONFIG_FlingLongSwipePortraitRight = "config_FlingLongSwipePortraitRight"; + public static final String CONFIG_FlingLongSwipeLandscapeLeft = "config_FlingLongSwipeLandscapeLeft"; + public static final String CONFIG_FlingLongSwipeLandscapeRight = "config_FlingLongSwipeLandscapeRight"; + public static final String CONFIG_FlingLongSwipeVerticalUp = "config_FlingLongSwipeVerticalUp"; + public static final String CONFIG_FlingLongSwipeVerticalDown = "config_FlingLongSwipeVerticalDown"; + public static final String CONFIG_pulsePathEffect_1 = "config_pulsePathEffect_1"; + public static final String CONFIG_pulsePathEffect_2 = "config_pulsePathEffect_2"; + public static final String CONFIG_pulsePathStrokeWidth = "config_pulsePathStrokeWidth"; + public static final String CONFIG_pulseFillColor = "config_pulseFillColor"; + public static final String CONFIG_pulseDivisions = "config_pulseDivisions"; + public static final String CONFIG_pulseDbFuzzFactor = "config_pulseDbFuzzFactor"; + public static final String CONFIG_pulseDbFuzz = "config_pulseDbFuzz"; + + private static final Map defMap = new HashMap(); + + static { + defMap.put(CONFIG_fling_touchslop_increase_factor, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_fling_touchslop_increase_factor, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_FlingLongSwipePortraitLeft, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_FlingLongSwipePortraitLeft, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_FlingLongSwipePortraitRight, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_FlingLongSwipePortraitRight, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_FlingLongSwipeLandscapeLeft, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_FlingLongSwipeLandscapeLeft, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_FlingLongSwipeLandscapeRight, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_FlingLongSwipeLandscapeRight, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_FlingLongSwipeVerticalUp, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_FlingLongSwipeVerticalUp, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_FlingLongSwipeVerticalDown, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_FlingLongSwipeVerticalDown, + ActionUtils.FORMAT_FLOAT, ActionUtils.DIMEN)); + defMap.put(CONFIG_pulsePathEffect_1, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulsePathEffect_1, ActionUtils.DIMEN_PIXEL)); + defMap.put(CONFIG_pulsePathEffect_2, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulsePathEffect_2, ActionUtils.DIMEN_PIXEL)); + defMap.put(CONFIG_pulsePathStrokeWidth, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulsePathStrokeWidth, ActionUtils.DIMEN_PIXEL)); + defMap.put(CONFIG_pulseFillColor, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulseFillColor, ActionUtils.COLOR)); + defMap.put(CONFIG_pulseDivisions, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulseDivisions, ActionUtils.INT)); + defMap.put(CONFIG_pulseDbFuzzFactor, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulseDbFuzzFactor, ActionUtils.INT)); + defMap.put(CONFIG_pulseDbFuzz, new ConfigHolder( + ActionUtils.PACKAGE_SYSTEMUI, CONFIG_pulseDbFuzz, ActionUtils.INT)); + } + + private static final Map configMap = new HashMap(); + + static { + configMap.put(SINGLE_LEFT_TAP_TAG, new ConfigMap(1, ActionConfig.PRIMARY)); + configMap.put(SINGLE_RIGHT_TAP_TAG, new ConfigMap(0, ActionConfig.PRIMARY)); + configMap.put(DOUBLE_LEFT_TAP_TAG, new ConfigMap(1, ActionConfig.THIRD)); + configMap.put(DOUBLE_RIGHT_TAP_TAG, new ConfigMap(0, ActionConfig.THIRD)); + configMap.put(LONG_LEFT_PRESS_TAG, new ConfigMap(1, ActionConfig.SECOND)); + configMap.put(LONG_RIGHT_PRESS_TAG, new ConfigMap(0, ActionConfig.SECOND)); + configMap.put(FLING_SHORT_LEFT_TAG, new ConfigMap(3, ActionConfig.PRIMARY)); + configMap.put(FLING_SHORT_RIGHT_TAG, new ConfigMap(2, ActionConfig.PRIMARY)); + configMap.put(FLING_LONG_LEFT_TAG, new ConfigMap(3, ActionConfig.SECOND)); + configMap.put(FLING_LONG_RIGHT_TAG, new ConfigMap(2, ActionConfig.SECOND)); + configMap.put(FLING_RIGHT_UP_TAG, new ConfigMap(4, ActionConfig.PRIMARY)); + configMap.put(FLING_LEFT_UP_TAG, new ConfigMap(4, ActionConfig.SECOND)); + } + + public static final String FLING_CONFIG_DEFAULT = + dl(FLING_DEF_BUTTONS) + + dl(RIGHT_TAP_TAG) + + dl(SystemAction.Home.mAction) + dl(SystemAction.Home.mLabelRes) + dl(EMPTY) // short tap + + dl(SystemAction.GoogleNowOnTap.mAction) + dl(SystemAction.GoogleNowOnTap.mLabelRes) + dl(EMPTY) // long press + + dl(SystemAction.LastApp.mAction) + dl(SystemAction.LastApp.mLabelRes) + dl(EMPTY) // double tap + + + dl(LEFT_TAP_TAG) + + dl(SystemAction.Home.mAction) + dl(SystemAction.Home.mLabelRes) + dl(EMPTY) // short tap + + dl(SystemAction.GoogleNowOnTap.mAction) + dl(SystemAction.GoogleNowOnTap.mLabelRes) + dl(EMPTY) // long press + + dl(SystemAction.ScreenOff.mAction) + dl(SystemAction.ScreenOff.mLabelRes) + dl(EMPTY) // double tap + + + dl(RIGHT_FLING_TAG) + + dl(SystemAction.Overview.mAction) + dl(SystemAction.Overview.mLabelRes) + dl(EMPTY) // short fling + + dl(SystemAction.Assistant.mAction) + dl(SystemAction.Assistant.mLabelRes) + dl(EMPTY) // long fling + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // super fling? + + + dl(LEFT_FLING) + + dl(SystemAction.Back.mAction) + dl(SystemAction.Back.mLabelRes) + dl(EMPTY) // short fling + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // long fling + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // super fling? + + + dl(UP_FLING) + + dl(SystemAction.SplitScreen.mAction) + dl(SystemAction.SplitScreen.mLabelRes) + dl(EMPTY) // right side (short fling only) + + dl(SystemAction.SplitScreen.mAction) + dl(SystemAction.SplitScreen.mLabelRes) + dl(EMPTY) // left side (short fling only) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + EMPTY; + + @Override + public int getConfigType() { + return FLING; + } + + @Override + public String getUri() { + return Settings.Secure.FLING_GESTURE_ACTIONS; + } + + @Override + public String getDefaultConfig() { + return FLING_CONFIG_DEFAULT; + } + + @Override + public int getMaxButtons() { + return FLING_MAX_BUTTONS; + } + + @Override + public Map getActionMap() { + return configMap; + } + + @Override + public Bundle getConfigs(Context context) { + return loadConfigsFromMap(context, defMap); + } + } + + public static class PiePrimary implements Defaults { + public static final int PIE_PRIMARY_MAX_BUTTONS = 3; + public static final String PIE_PRIMARY_DEF_BUTTONS = "3"; + public static final String PIE_BACK_BUTTON_TAG = "pie_button_back"; + public static final String PIE_HOME_BUTTON_TAG = "pie_button_home"; + public static final String PIE_OVERVIEW_BUTTON_TAG = "pie_button_overview"; + + public static final String PIE_BACK_BUTTON_SINGLE_TAP_TAG = "pie_button_back_single_tap"; + public static final String PIE_HOME_BUTTON_SINGLE_TAP_TAG = "pie_button_home_single_tap"; + public static final String PIE_OVERVIEW_BUTTON_SINGLE_TAP_TAG = "pie_button_overview_single_tap"; + + public static final String PIE_BACK_BUTTON_LONG_PRESS_TAG = "pie_button_back_long_press"; + public static final String PIE_HOME_BUTTON_LONG_PRESS_TAG = "pie_button_home_long_press"; + public static final String PIE_OVERVIEW_BUTTON_LONG_PRESS_TAG = "pie_button_overview_long_press"; + + private static final Map configMap = new HashMap(); + + static { + configMap.put(PIE_BACK_BUTTON_SINGLE_TAP_TAG, new ConfigMap(0, ActionConfig.PRIMARY)); + configMap.put(PIE_HOME_BUTTON_SINGLE_TAP_TAG, new ConfigMap(1, ActionConfig.PRIMARY)); + configMap.put(PIE_OVERVIEW_BUTTON_SINGLE_TAP_TAG, new ConfigMap(2, ActionConfig.PRIMARY)); + configMap.put(PIE_BACK_BUTTON_LONG_PRESS_TAG, new ConfigMap(0, ActionConfig.SECOND)); + configMap.put(PIE_HOME_BUTTON_LONG_PRESS_TAG, new ConfigMap(1, ActionConfig.SECOND)); + configMap.put(PIE_OVERVIEW_BUTTON_LONG_PRESS_TAG, new ConfigMap(2, ActionConfig.SECOND)); + } + + public static final String PIE_PRIMARY_CONFIG_DEFAULT = + dl(PIE_PRIMARY_DEF_BUTTONS) + + dl(PIE_BACK_BUTTON_TAG) + + dl(SystemAction.Back.mAction) + dl(SystemAction.Back.mLabelRes) + dl(EMPTY) // single tap (PRIMARY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // long press (SECOND) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // double tap (NO-OP on Pie) + + + dl(PIE_HOME_BUTTON_TAG) + + dl(SystemAction.Home.mAction) + dl(SystemAction.Home.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(PIE_OVERVIEW_BUTTON_TAG) + + dl(SystemAction.Overview.mAction) + dl(SystemAction.Overview.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + EMPTY; // don't delimit final string + + + @Override + public int getConfigType() { + return PIE_PRIMARY; + } + + @Override + public String getUri() { + //return Settings.System.PIE_BUTTONS_CONFIG; + return "pie_primary_config"; + } + + @Override + public String getDefaultConfig() { + return PIE_PRIMARY_CONFIG_DEFAULT; + } + + @Override + public int getMaxButtons() { + return PIE_PRIMARY_MAX_BUTTONS; + } + + @Override + public Map getActionMap() { + return configMap; + } + + @Override + public Bundle getConfigs(Context context) { + // TODO Auto-generated method stub + return null; + } + } + + public static class PieSecond implements Defaults { + public static final int PIE_SECOND_MAX_BUTTONS = 7; + public static final String PIE_SECOND_DEF_BUTTONS = "5"; + public static final String PIE_BUTTON1_TAG = "pie_button_1"; + public static final String PIE_BUTTON2_TAG = "pie_button_2"; + public static final String PIE_BUTTON3_TAG = "pie_button_3"; + public static final String PIE_BUTTON4_TAG = "pie_button_4"; + public static final String PIE_BUTTON5_TAG = "pie_button_5"; + public static final String PIE_BUTTON6_TAG = "pie_button_6"; + public static final String PIE_BUTTON7_TAG = "pie_button_7"; + + public static final String PIE_SECOND_BUTTON1_SINGLE_TAP_TAG = "pie_second_button_1_single_tap"; + public static final String PIE_SECOND_BUTTON2_SINGLE_TAP_TAG = "pie_second_button_2_single_tap"; + public static final String PIE_SECOND_BUTTON3_SINGLE_TAP_TAG = "pie_second_button_3_single_tap"; + public static final String PIE_SECOND_BUTTON4_SINGLE_TAP_TAG = "pie_second_button_4_single_tap"; + public static final String PIE_SECOND_BUTTON5_SINGLE_TAP_TAG = "pie_second_button_5_single_tap"; + public static final String PIE_SECOND_BUTTON6_SINGLE_TAP_TAG = "pie_second_button_6_single_tap"; + public static final String PIE_SECOND_BUTTON7_SINGLE_TAP_TAG = "pie_second_button_7_single_tap"; + + public static final String PIE_SECOND_BUTTON1_LONG_PRESS_TAG = "pie_second_button_1_long_press"; + public static final String PIE_SECOND_BUTTON2_LONG_PRESS_TAG = "pie_second_button_2_long_press"; + public static final String PIE_SECOND_BUTTON3_LONG_PRESS_TAG = "pie_second_button_3_long_press"; + public static final String PIE_SECOND_BUTTON4_LONG_PRESS_TAG = "pie_second_button_4_long_press"; + public static final String PIE_SECOND_BUTTON5_LONG_PRESS_TAG = "pie_second_button_5_long_press"; + public static final String PIE_SECOND_BUTTON6_LONG_PRESS_TAG = "pie_second_button_6_long_press"; + public static final String PIE_SECOND_BUTTON7_LONG_PRESS_TAG = "pie_second_button_7_long_press"; + + private static final Map configMap = new HashMap(); + + static { + configMap.put(PIE_SECOND_BUTTON1_SINGLE_TAP_TAG, new ConfigMap(0, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON2_SINGLE_TAP_TAG, new ConfigMap(1, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON3_SINGLE_TAP_TAG, new ConfigMap(2, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON4_SINGLE_TAP_TAG, new ConfigMap(3, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON5_SINGLE_TAP_TAG, new ConfigMap(4, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON6_SINGLE_TAP_TAG, new ConfigMap(5, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON7_SINGLE_TAP_TAG, new ConfigMap(6, ActionConfig.PRIMARY)); + configMap.put(PIE_SECOND_BUTTON1_LONG_PRESS_TAG, new ConfigMap(0, ActionConfig.SECOND)); + configMap.put(PIE_SECOND_BUTTON2_LONG_PRESS_TAG, new ConfigMap(1, ActionConfig.SECOND)); + configMap.put(PIE_SECOND_BUTTON3_LONG_PRESS_TAG, new ConfigMap(2, ActionConfig.SECOND)); + configMap.put(PIE_SECOND_BUTTON4_LONG_PRESS_TAG, new ConfigMap(3, ActionConfig.SECOND)); + configMap.put(PIE_SECOND_BUTTON5_LONG_PRESS_TAG, new ConfigMap(4, ActionConfig.SECOND)); + configMap.put(PIE_SECOND_BUTTON6_LONG_PRESS_TAG, new ConfigMap(5, ActionConfig.SECOND)); + configMap.put(PIE_SECOND_BUTTON7_LONG_PRESS_TAG, new ConfigMap(6, ActionConfig.SECOND)); + } + + public static final String PIE_SECOND_CONFIG_DEFAULT = + dl(PIE_SECOND_DEF_BUTTONS) + + dl(PIE_BUTTON1_TAG) + + dl(SystemAction.PowerMenu.mAction) + dl(SystemAction.PowerMenu.mLabelRes) + dl(EMPTY) // single tap (PRIMARY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // long press (SECOND) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // double tap (NO-OP on Pie) + + + dl(PIE_BUTTON2_TAG) + + dl(SystemAction.NotificationPanel.mAction) + dl(SystemAction.NotificationPanel.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(PIE_BUTTON3_TAG) + + dl(SystemAction.Assistant.mAction) + dl(SystemAction.Assistant.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(PIE_BUTTON4_TAG) + + dl(SystemAction.Screenshot.mAction) + dl(SystemAction.Screenshot.mLabelRes) + dl(EMPTY) + + dl(SystemAction.RegionScreenshot.mAction) + dl(SystemAction.RegionScreenshot.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + + dl(PIE_BUTTON5_TAG) + + dl(SystemAction.LastApp.mAction) + dl(SystemAction.LastApp.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) + + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + EMPTY; + + @Override + public int getConfigType() { + return PIE_SECONDARY; + } + + @Override + public String getUri() { + //return Settings.System.PIE_BUTTONS_CONFIG_SECOND_LAYER; + return "pie_second_config"; + } + + @Override + public String getDefaultConfig() { + return PIE_SECOND_CONFIG_DEFAULT; + } + + @Override + public int getMaxButtons() { + return PIE_SECOND_MAX_BUTTONS; + } + + @Override + public Map getActionMap() { + return configMap; + } + + @Override + public Bundle getConfigs(Context context) { + // TODO Auto-generated method stub + return null; + } + + } + + private static Bundle loadConfigsFromMap(Context ctx, Map configMap) { + Bundle b = new Bundle(); + for (Map.Entry entry : configMap.entrySet()) { + ConfigHolder holder = entry.getValue(); + Object obj = ActionUtils.getValue(ctx, holder.name, holder.type, holder.format, + holder.pkg); + ActionUtils.putValue(holder.name, obj, holder.type, b); + } + return b; + } + + private static class ConfigHolder { + public String pkg; + public String name; + public String format; + public String type; + + public ConfigHolder(String pkg, String name, String type) { + this(pkg, name, null, type); + } + + public ConfigHolder(String pkg, String name, String format, String type) { + this.pkg = pkg; + this.name = name; + this.format = format; + this.type = type; + } + } + + public static class ConfigMap { + public int button = -1; + public int action = -1; + + public ConfigMap() { + }; + + public ConfigMap(int button, int action) { + this.button = button; + this.action = action; + } + } + + public static final int PIE_PRIMARY_MAX_BUTTONS = 5; + public static final int PIE_SECONDAY_MAX_BUTTONS = 7; + +} diff --git a/core/java/com/android/internal/utils/ActionHandler.java b/core/java/com/android/internal/utils/ActionHandler.java new file mode 100644 index 000000000000..f8d54ac65864 --- /dev/null +++ b/core/java/com/android/internal/utils/ActionHandler.java @@ -0,0 +1,1137 @@ +/* + * Copyright (C) 2015 The TeamEos Project + * Copyright (C) 2016-2017 The DirtyUnicorns 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. + * + * Launches actions assigned to widgets. Creates bundles of state based + * on the type of action passed. + * + */ + +package com.android.internal.utils; + +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.ActivityOptions; +import android.app.IActivityManager; +import android.app.NotificationManager; +import android.app.SearchManager; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.app.usage.UsageStats; +import android.app.usage.UsageStatsManager; +import android.bluetooth.BluetoothAdapter; +import android.content.ActivityNotFoundException; +import android.content.ContentResolver; +import android.content.Context; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ParceledListSlice; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.hardware.input.InputManager; +import android.media.AudioManager; +import android.media.ToneGenerator; +import android.media.session.MediaSessionLegacyHelper; +import android.net.ConnectivityManager; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.PowerManager; +import android.os.Process; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.os.UserHandle; +import android.os.Vibrator; +import android.provider.Settings; +import android.service.wallpaper.WallpaperService; +import android.text.TextUtils; +import android.util.Log; +import android.util.Slog; +import android.view.IWindowManager; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.WindowManagerGlobal; +//import android.view.WindowManagerPolicyControl; +import android.view.inputmethod.InputMethodManager; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.utils.Config.ActionConfig; + +public class ActionHandler { + public static String TAG = ActionHandler.class.getSimpleName(); + + public static final String SYSTEM_PREFIX = "task"; + public static final String DARK_SUFFIX = "_dark"; + public static final String SYSTEMUI = "com.android.systemui"; + + // track and filter special actions + public static final String TASK_IME = "task_ime"; + public static final String TASK_MEDIA = "task_media"; + public static final String TASK_SOUNDMODE = "task_soundmode"; + + public static final String SYSTEMUI_TASK_NO_ACTION = "task_no_action"; + public static final String SYSTEMUI_TASK_SETTINGS_PANEL = "task_settings_panel"; + public static final String SYSTEMUI_TASK_NOTIFICATION_PANEL = "task_notification_panel"; + public static final String SYSTEMUI_TASK_SCREENSHOT = "task_screenshot"; + public static final String SYSTEMUI_TASK_REGION_SCREENSHOT = "task_region_screenshot"; + public static final String SYSTEMUI_TASK_SCREENRECORD = "task_screenrecord"; + // public static final String SYSTEMUI_TASK_AUDIORECORD = + // "task_audiorecord"; + public static final String SYSTEMUI_TASK_EXPANDED_DESKTOP = "task_expanded_desktop"; + public static final String SYSTEMUI_TASK_SCREENOFF = "task_screenoff"; + public static final String SYSTEMUI_TASK_KILL_PROCESS = "task_killcurrent"; + public static final String SYSTEMUI_TASK_ASSIST = "task_assist"; + public static final String SYSTEMUI_TASK_GOOGLE_NOW_ON_TAP = "task_google_now_on_tap"; + public static final String SYSTEMUI_TASK_POWER_MENU = "task_powermenu"; + public static final String SYSTEMUI_TASK_TORCH = "task_torch"; + public static final String SYSTEMUI_TASK_CAMERA = "task_camera"; + public static final String SYSTEMUI_TASK_BT = "task_bt"; + public static final String SYSTEMUI_TASK_WIFI = "task_wifi"; + public static final String SYSTEMUI_TASK_WIFIAP = "task_wifiap"; + public static final String SYSTEMUI_TASK_RECENTS = "task_recents"; + public static final String SYSTEMUI_TASK_LAST_APP = "task_last_app"; + public static final String SYSTEMUI_TASK_VOICE_SEARCH = "task_voice_search"; + public static final String SYSTEMUI_TASK_APP_SEARCH = "task_app_search"; + public static final String SYSTEMUI_TASK_MENU = "task_menu"; + public static final String SYSTEMUI_TASK_BACK = "task_back"; + public static final String SYSTEMUI_TASK_HOME = "task_home"; + public static final String SYSTEMUI_TASK_IME_SWITCHER = "task_ime_switcher"; + public static final String SYSTEMUI_TASK_IME_NAVIGATION_LEFT = "task_ime_navigation_left"; + public static final String SYSTEMUI_TASK_IME_NAVIGATION_RIGHT = "task_ime_navigation_right"; + public static final String SYSTEMUI_TASK_IME_NAVIGATION_UP = "task_ime_navigation_up"; + public static final String SYSTEMUI_TASK_IME_NAVIGATION_DOWN = "task_ime_navigation_down"; + public static final String SYSTEMUI_TASK_MEDIA_PREVIOUS = "task_media_previous"; + public static final String SYSTEMUI_TASK_MEDIA_NEXT = "task_media_next"; + public static final String SYSTEMUI_TASK_MEDIA_PLAY_PAUSE = "task_media_play_pause"; + public static final String SYSTEMUI_TASK_SOUNDMODE_VIB = "task_soundmode_vib"; + public static final String SYSTEMUI_TASK_SOUNDMODE_SILENT = "task_soundmode_silent"; + public static final String SYSTEMUI_TASK_SOUNDMODE_VIB_SILENT = "task_soundmode_vib_silent"; + public static final String SYSTEMUI_TASK_WAKE_DEVICE = "task_wake_device"; + public static final String SYSTEMUI_TASK_STOP_SCREENPINNING = "task_stop_screenpinning"; + public static final String SYSTEMUI_TASK_CLEAR_NOTIFICATIONS = "task_clear_notifications"; + public static final String SYSTEMUI_TASK_VOLUME_PANEL = "task_volume_panel"; + public static final String SYSTEMUI_TASK_EDITING_SMARTBAR = "task_editing_smartbar"; + public static final String SYSTEMUI_TASK_SPLIT_SCREEN = "task_split_screen"; + public static final String SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT = "task_one_handed_mode_left"; + public static final String SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT = "task_one_handed_mode_right"; + public static final String SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH = "task_assistant_sound_search"; + + public static final String INTENT_SHOW_POWER_MENU = "action_handler_show_power_menu"; + public static final String INTENT_TOGGLE_SCREENRECORD = "action_handler_toggle_screenrecord"; + public static final String INTENT_SCREENSHOT = "action_handler_screenshot"; + public static final String INTENT_REGION_SCREENSHOT = "action_handler_region_screenshot"; + + // remove actions from here as they come back on deck + static final Set sDisabledActions = new HashSet(); + static { + sDisabledActions.add(SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT); + sDisabledActions.add(SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT); + sDisabledActions.add(SYSTEMUI_TASK_EXPANDED_DESKTOP); + sDisabledActions.add(SYSTEMUI_TASK_APP_SEARCH); + } + + static enum SystemAction { + NoAction(SYSTEMUI_TASK_NO_ACTION, SYSTEMUI, "label_action_no_action", "ic_sysbar_no_action"), + SettingsPanel(SYSTEMUI_TASK_SETTINGS_PANEL, SYSTEMUI, "label_action_settings_panel", "ic_sysbar_settings_panel"), + NotificationPanel(SYSTEMUI_TASK_NOTIFICATION_PANEL, SYSTEMUI, "label_action_notification_panel", "ic_sysbar_notification_panel"), + Screenshot(SYSTEMUI_TASK_SCREENSHOT, SYSTEMUI, "label_action_screenshot", "ic_sysbar_screenshot"), + RegionScreenshot(SYSTEMUI_TASK_REGION_SCREENSHOT, SYSTEMUI, "label_action_region_screenshot", "ic_sysbar_region_screenshot"), + Screenrecord(SYSTEMUI_TASK_SCREENRECORD, SYSTEMUI, "label_action_screenrecord", "ic_sysbar_record_screen"), + ExpandedDesktop(SYSTEMUI_TASK_EXPANDED_DESKTOP, SYSTEMUI, "label_action_expanded_desktop", "ic_sysbar_expanded_desktop"), + ScreenOff(SYSTEMUI_TASK_SCREENOFF, SYSTEMUI, "label_action_screen_off", "ic_sysbar_screen_off"), + KillApp(SYSTEMUI_TASK_KILL_PROCESS, SYSTEMUI, "label_action_force_close_app", "ic_sysbar_killtask"), + Assistant(SYSTEMUI_TASK_ASSIST, SYSTEMUI, "label_action_search_assistant", "ic_sysbar_assist"), + GoogleNowOnTap(SYSTEMUI_TASK_GOOGLE_NOW_ON_TAP, SYSTEMUI, "label_action_google_now_on_tap", "ic_sysbar_google_now_on_tap"), + VoiceSearch(SYSTEMUI_TASK_VOICE_SEARCH, SYSTEMUI, "label_action_voice_search", "ic_sysbar_search"), + InAppSearch(SYSTEMUI_TASK_APP_SEARCH, SYSTEMUI, "label_action_in_app_search", "ic_sysbar_in_app_search"), + Flashlight(SYSTEMUI_TASK_TORCH, SYSTEMUI, "label_action_flashlight", "ic_sysbar_torch"), + Bluetooth(SYSTEMUI_TASK_BT, SYSTEMUI, "label_action_bluetooth", "ic_sysbar_bt"), + WiFi(SYSTEMUI_TASK_WIFI, SYSTEMUI, "label_action_wifi", "ic_sysbar_wifi"), + Hotspot(SYSTEMUI_TASK_WIFIAP, SYSTEMUI, "label_action_hotspot", "ic_sysbar_hotspot"), + LastApp(SYSTEMUI_TASK_LAST_APP, SYSTEMUI, "label_action_last_app", "ic_sysbar_lastapp"), + Overview(SYSTEMUI_TASK_RECENTS, SYSTEMUI, "label_action_overview", "ic_smartbar_recent"), + PowerMenu(SYSTEMUI_TASK_POWER_MENU, SYSTEMUI, "label_action_power_menu", "ic_sysbar_power_menu"), + Menu(SYSTEMUI_TASK_MENU, SYSTEMUI, "label_action_menu", "ic_smartbar_menu"), + Back(SYSTEMUI_TASK_BACK, SYSTEMUI, "label_action_back", "ic_smartbar_back"), + Home(SYSTEMUI_TASK_HOME, SYSTEMUI, "label_action_home", "ic_smartbar_home"), + Ime(SYSTEMUI_TASK_IME_SWITCHER, SYSTEMUI, "label_action_ime_switcher", "ic_ime_switcher_smartbar"), + StopScreenPinning(SYSTEMUI_TASK_STOP_SCREENPINNING, SYSTEMUI, "label_action_stop_screenpinning", "ic_smartbar_screen_pinning_off"), + ImeArrowDown(SYSTEMUI_TASK_IME_NAVIGATION_DOWN, SYSTEMUI, "label_action_ime_down", "ic_sysbar_ime_down"), + ImeArrowLeft(SYSTEMUI_TASK_IME_NAVIGATION_LEFT, SYSTEMUI, "label_action_ime_left", "ic_sysbar_ime_left"), + ImeArrowRight(SYSTEMUI_TASK_IME_NAVIGATION_RIGHT, SYSTEMUI, "label_action_ime_right", "ic_sysbar_ime_right"), + ImeArrowUp(SYSTEMUI_TASK_IME_NAVIGATION_UP, SYSTEMUI, "label_action_ime_up", "ic_sysbar_ime_up"), + ClearNotifications(SYSTEMUI_TASK_CLEAR_NOTIFICATIONS, SYSTEMUI, "label_action_clear_notifications", "ic_sysbar_clear_notifications"), + VolumePanel(SYSTEMUI_TASK_VOLUME_PANEL, SYSTEMUI, "label_action_volume_panel", "ic_sysbar_volume_panel"), + EditingSmartbar(SYSTEMUI_TASK_EDITING_SMARTBAR, SYSTEMUI, "label_action_editing_smartbar", "ic_sysbar_editing_smartbar"), + SplitScreen(SYSTEMUI_TASK_SPLIT_SCREEN, SYSTEMUI, "label_action_split_screen", "ic_smartbar_docked"), + OneHandedModeLeft(SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT, SYSTEMUI, "label_action_one_handed_mode_left", "ic_sysbar_one_handed_mode_left"), + OneHandedModeRight(SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT, SYSTEMUI, "label_action_one_handed_mode_right", "ic_sysbar_one_handed_mode_right"), + MediaArrowLeft(SYSTEMUI_TASK_MEDIA_PREVIOUS, SYSTEMUI, "label_action_media_left", "ic_skip_previous"), + MediaArrowRight(SYSTEMUI_TASK_MEDIA_NEXT, SYSTEMUI, "label_action_media_right", "ic_skip_next"), + AssistantSoundSearch(SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH, SYSTEMUI, "label_action_assistant_sound_search", "ic_assistant_sound_search"), + PlayPause(SYSTEMUI_TASK_MEDIA_PLAY_PAUSE, SYSTEMUI, "label_action_play_pause", "ic_sysbar_play_pause"), + RingVibeSilent(SYSTEMUI_TASK_SOUNDMODE_VIB_SILENT, SYSTEMUI, "label_action_ring_vibe_silent", "ic_sysbar_ring_vibe_silent"), + Camera(SYSTEMUI_TASK_CAMERA, SYSTEMUI, "label_action_camera", "ic_sysbar_camera"); + + String mAction; + String mResPackage; + String mLabelRes; + String mIconRes; + String mDarkIconRes; + + private SystemAction(String action, String resPackage, String labelRes, String iconRes) { + mAction = action; + mResPackage = resPackage; + mLabelRes = labelRes; + mIconRes = iconRes; + mDarkIconRes = iconRes + DARK_SUFFIX; + } + + private ActionConfig create(Context ctx) { + return new ActionConfig(ctx, mAction); + } + } + + /* + * Enumerated system actions with label and drawable support + */ + static SystemAction[] systemActions = new SystemAction[] { + SystemAction.NoAction, SystemAction.SettingsPanel, + SystemAction.NotificationPanel, SystemAction.Screenshot, + SystemAction.ScreenOff, SystemAction.KillApp, + SystemAction.Assistant, SystemAction.GoogleNowOnTap, + SystemAction.Flashlight, SystemAction.Bluetooth, + SystemAction.WiFi, SystemAction.Hotspot, + SystemAction.LastApp, SystemAction.PowerMenu, + SystemAction.Overview,SystemAction.Menu, + SystemAction.Back, SystemAction.VoiceSearch, + SystemAction.Home, SystemAction.ExpandedDesktop, + SystemAction.Screenrecord, SystemAction.Ime, + SystemAction.StopScreenPinning, SystemAction.ImeArrowDown, + SystemAction.ImeArrowLeft, SystemAction.ImeArrowRight, + SystemAction.ImeArrowUp, SystemAction.InAppSearch, + SystemAction.VolumePanel, SystemAction.ClearNotifications, + SystemAction.EditingSmartbar, SystemAction.SplitScreen, + SystemAction.RegionScreenshot, SystemAction.OneHandedModeLeft, + SystemAction.OneHandedModeRight, SystemAction.MediaArrowLeft, + SystemAction.MediaArrowRight, SystemAction.AssistantSoundSearch, + SystemAction.PlayPause, SystemAction.RingVibeSilent, + SystemAction.Camera + }; + + public static class ActionIconResources { + Drawable[] mDrawables; + Drawable[] mDarkDrawables; + Map mIndexMap; + + public ActionIconResources(Resources res) { + mDrawables = new Drawable[systemActions.length]; + mDarkDrawables = new Drawable[systemActions.length]; + mIndexMap = new HashMap(); + for (int i = 0; i < systemActions.length; i++) { + mIndexMap.put(systemActions[i].mAction, i); + mDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mIconRes, + systemActions[i].mResPackage); + mDarkDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mDarkIconRes, + systemActions[i].mResPackage); + } + } + + public void updateResources(Resources res) { + for (int i = 0; i < mDrawables.length; i++) { + mDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mIconRes, + systemActions[i].mResPackage); + mDarkDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mDarkIconRes, + systemActions[i].mResPackage); + } + } + + public Drawable getActionDrawable(String action) { + return mDrawables[mIndexMap.get(action)]; + } + + public Drawable getDarkActionDrawable(String action) { + return mDarkDrawables[mIndexMap.get(action)]; + } + } + + /* + * Default list to display in an action picker + * Filter by device capabilities and actions used internally + * but we don't really want as assignable + */ + public static ArrayList getSystemActions(Context context) { + ArrayList bundle = new ArrayList(); + for (int i = 0; i < systemActions.length; i++) { + ActionConfig c = systemActions[i].create(context); + String action = c.getAction(); + if (sDisabledActions.contains(action)) { + continue; + } + if (TextUtils.equals(action, SYSTEMUI_TASK_STOP_SCREENPINNING) + || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_DOWN) + || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_LEFT) + || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_RIGHT) + || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_UP) + || TextUtils.equals(action, SYSTEMUI_TASK_IME_SWITCHER)) { + continue; + } else if (TextUtils.equals(action, SYSTEMUI_TASK_WIFIAP) + && !ActionUtils.deviceSupportsMobileData(context)) { + continue; + } else if (TextUtils.equals(action, SYSTEMUI_TASK_BT) + && !ActionUtils.deviceSupportsBluetooth()) { + continue; + } else if (TextUtils.equals(action, SYSTEMUI_TASK_TORCH) + && !ActionUtils.deviceSupportsFlashLight(context)) { + continue; + } else if (TextUtils.equals(action, SYSTEMUI_TASK_CAMERA) + && !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { + continue; + } else if (TextUtils.equals(action, SYSTEMUI_TASK_EDITING_SMARTBAR)) { + // don't allow smartbar editor on Fling + if (Settings.Secure.getIntForUser(context.getContentResolver(), + Settings.Secure.NAVIGATION_BAR_MODE, 0, + UserHandle.USER_CURRENT) != 1) { + continue; + } + } else if (TextUtils.equals(action, SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH)) { + if (!ActionUtils.isPackageInstalled(context, + "com.google.android.googlequicksearchbox")) { + continue; + } + } + bundle.add(c); + } + Collections.sort(bundle); + return bundle; + } + + private static final class StatusBarHelper { + private static boolean isPreloaded = false; + private static IStatusBarService mService = null; + + private static IStatusBarService getStatusBarService() { + synchronized (StatusBarHelper.class) { + if (mService == null) { + try { + mService = IStatusBarService.Stub.asInterface( + ServiceManager.getService("statusbar")); + } catch (Exception e) { + } + } + return mService; + } + } + + private static void dispatchNavigationEditorResult(Intent intent) { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.dispatchNavigationEditorResults(intent); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } + + private static void toggleNavigationEditor() { + IStatusBarService service = getStatusBarService(); + try { + service.toggleNavigationEditor(); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + private static void toggleFlashlight() { + IStatusBarService service = getStatusBarService(); + try { + service.toggleFlashlight(); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + private static void toggleRecentsApps() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + sendCloseSystemWindows("recentapps"); + service.toggleRecentApps(); + } catch (RemoteException e) { + return; + } + isPreloaded = false; + } + } + + private static void cancelPreloadRecentApps() { + if (isPreloaded == false) + return; + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.cancelPreloadRecentApps(); + } catch (Exception e) { + return; + } + } + isPreloaded = false; + } + + private static void preloadRecentApps() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.preloadRecentApps(); + } catch (RemoteException e) { + isPreloaded = false; + return; + } + isPreloaded = true; + } + } + + private static void expandNotificationPanel() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.expandNotificationsPanel(); + } catch (RemoteException e) { + } + } + } + + private static void expandSettingsPanel() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.expandSettingsPanel(null); + } catch (RemoteException e) { + } + } + } + + private static void fireGoogleNowOnTap() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.startAssist(new Bundle()); + } catch (RemoteException e) { + } + } + } + + private static void splitScreen() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.toggleSplitScreen(); + } catch (RemoteException e) { + } + } + } +/* + private static void fireIntentAfterKeyguard(Intent intent) { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.showCustomIntentAfterKeyguard(intent); + } catch (RemoteException e) { + } + } + } +*/ + private static void clearAllNotifications() { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.onClearAllNotifications(ActivityManager.getCurrentUser()); + } catch (RemoteException e) { + } + } + } + + private static void sendSystemKeyToStatusBar(int keyCode) { + IStatusBarService service = getStatusBarService(); + if (service != null) { + try { + service.handleSystemKey(keyCode); + } catch (RemoteException e) { + } + } + } + } + + public static void toggleRecentApps() { + StatusBarHelper.toggleRecentsApps(); + } + + public static void cancelPreloadRecentApps() { + StatusBarHelper.cancelPreloadRecentApps(); + } + + public static void preloadRecentApps() { + StatusBarHelper.preloadRecentApps(); + } +/* + public static void performTaskFromKeyguard(Context ctx, String action) { + // null: throw it out + if (action == null) { + return; + } + // not a system action, should be intent + if (!action.startsWith(SYSTEM_PREFIX)) { + Intent intent = DUActionUtils.getIntent(action); + if (intent == null) { + return; + } + StatusBarHelper.fireIntentAfterKeyguard(intent); + } else { + performTask(ctx, action); + } + } +*/ + public static void dispatchNavigationEditorResult(Intent intent) { + StatusBarHelper.dispatchNavigationEditorResult(intent); + } + + public static void performTask(Context context, String action) { + // null: throw it out + if (action == null) { + return; + } + if (sDisabledActions.contains(action)) { + return; + } + // not a system action, should be intent + if (!action.startsWith(SYSTEM_PREFIX)) { + Intent intent = ActionUtils.getIntent(action); + if (intent == null) { + return; + } + launchActivity(context, intent); + return; + } else if (action.equals(SYSTEMUI_TASK_NO_ACTION)) { + return; + } else if (action.equals(SYSTEMUI_TASK_KILL_PROCESS)) { + killProcess(context); + return; + } else if (action.equals(SYSTEMUI_TASK_SCREENSHOT)) { + sendCommandToWindowManager(new Intent(INTENT_SCREENSHOT)); + return; + } else if (action.equals(SYSTEMUI_TASK_REGION_SCREENSHOT)) { + sendCommandToWindowManager(new Intent(INTENT_REGION_SCREENSHOT)); + return; + } else if (action.equals(SYSTEMUI_TASK_SCREENRECORD)) { + sendCommandToWindowManager(new Intent(INTENT_TOGGLE_SCREENRECORD)); + return; + // } else if (action.equals(SYSTEMUI_TASK_AUDIORECORD)) { + // takeAudiorecord(); +// } else if (action.equals(SYSTEMUI_TASK_EXPANDED_DESKTOP)) { +// toggleExpandedDesktop(context); +// return; + } else if (action.equals(SYSTEMUI_TASK_SCREENOFF)) { + screenOff(context); + return; + } else if (action.equals(SYSTEMUI_TASK_WAKE_DEVICE)) { + PowerManager powerManager = + (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (!powerManager.isScreenOn()) { + powerManager.wakeUp(SystemClock.uptimeMillis()); + } + return; + } else if (action.equals(SYSTEMUI_TASK_ASSIST)) { + launchAssistAction(context); + return; + } else if (action.equals(SYSTEMUI_TASK_GOOGLE_NOW_ON_TAP)) { + StatusBarHelper.fireGoogleNowOnTap(); + return; + } else if (action.equals(SYSTEMUI_TASK_POWER_MENU)) { + sendCommandToWindowManager(new Intent(INTENT_SHOW_POWER_MENU)); + return; + } else if (action.equals(SYSTEMUI_TASK_TORCH)) { + StatusBarHelper.toggleFlashlight(); + return; + } else if (action.equals(SYSTEMUI_TASK_CAMERA)) { + launchCamera(context); + return; + } else if (action.equals(SYSTEMUI_TASK_WIFI)) { + toggleWifi(context); + return; + } else if (action.equals(SYSTEMUI_TASK_WIFIAP)) { + toggleWifiAP(context); + return; + } else if (action.equals(SYSTEMUI_TASK_BT)) { + toggleBluetooth(); + return; + } else if (action.equals(SYSTEMUI_TASK_RECENTS)) { + toggleRecentApps(); + return; + } else if (action.equals(SYSTEMUI_TASK_LAST_APP)) { + switchToLastApp(context); + return; + } else if (action.equals(SYSTEMUI_TASK_SETTINGS_PANEL)) { + StatusBarHelper.expandSettingsPanel(); + return; + } else if (action.equals(SYSTEMUI_TASK_NOTIFICATION_PANEL)) { + StatusBarHelper.expandNotificationPanel(); + return; + } else if (action.equals(SYSTEMUI_TASK_VOICE_SEARCH)) { + launchVoiceSearch(context); + return; + } else if (action.equals(SYSTEMUI_TASK_APP_SEARCH)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_SEARCH); + return; + } else if (action.equals(SYSTEMUI_TASK_MENU)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_MENU); + return; + } else if (action.equals(SYSTEMUI_TASK_BACK)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_BACK); + return; + } else if (action.equals(SYSTEMUI_TASK_HOME)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_HOME); + return; + } else if (action.equals(SYSTEMUI_TASK_IME_SWITCHER)) { + ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)) + .showInputMethodPicker(true /* showAuxiliarySubtypes */); + return; +// } else if (action.equals(SYSTEMUI_TASK_STOP_SCREENPINNING)) { +// turnOffLockTask(); +// return; + } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_RIGHT)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_RIGHT); + return; + } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_UP)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_UP); + return; + } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_DOWN)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_DOWN); + return; + } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_LEFT)) { + triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_LEFT); + return; + } else if (action.equals(SYSTEMUI_TASK_MEDIA_PREVIOUS)) { + //StatusBarHelper.sendSystemKeyToStatusBar(KeyEvent.KEYCODE_MEDIA_PREVIOUS); + dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PREVIOUS, context); + return; + } else if (action.equals(SYSTEMUI_TASK_MEDIA_NEXT)) { + //StatusBarHelper.sendSystemKeyToStatusBar(KeyEvent.KEYCODE_MEDIA_NEXT); + dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_NEXT, context); + return; + } else if (action.equals(SYSTEMUI_TASK_MEDIA_PLAY_PAUSE)) { + //StatusBarHelper.sendSystemKeyToStatusBar(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE); + dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, context); + return; + } else if (action.equals(SYSTEMUI_TASK_SOUNDMODE_VIB_SILENT)) { + toggleVibeSilent(context); + return; + } else if (action.equals(SYSTEMUI_TASK_CLEAR_NOTIFICATIONS)) { + StatusBarHelper.clearAllNotifications(); + return; + } else if (action.equals(SYSTEMUI_TASK_VOLUME_PANEL)) { + volumePanel(context); + return; + } else if (action.equals(SYSTEMUI_TASK_EDITING_SMARTBAR)) { + StatusBarHelper.toggleNavigationEditor(); + return; + } else if (action.equals(SYSTEMUI_TASK_SPLIT_SCREEN)) { + StatusBarHelper.splitScreen(); + return; + } else if (action.equals(SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT)) { +// toggleOneHandedMode(context, "left"); + return; + } else if (action.equals(SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT)) { +// toggleOneHandedMode(context, "right"); + return; + } else if (action.equals(SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH)) { + startAssistantSoundSearch(context); + return; + } + } + + public static void toggleVibeSilent(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + + switch (am.getRingerMode()) { + case AudioManager.RINGER_MODE_NORMAL: + if (vibrator.hasVibrator()) { + am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + } + break; + case AudioManager.RINGER_MODE_VIBRATE: + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + NotificationManager notificationManager = (NotificationManager) context + .getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.setInterruptionFilter( + NotificationManager.INTERRUPTION_FILTER_PRIORITY); + break; + case AudioManager.RINGER_MODE_SILENT: + am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + break; + } + } + + public static boolean isActionKeyEvent(String action) { + if (action.equals(SYSTEMUI_TASK_HOME) + || action.equals(SYSTEMUI_TASK_BACK) +// || action.equals(SYSTEMUI_TASK_SEARCH) + || action.equals(SYSTEMUI_TASK_MENU) +// || action.equals(ActionConstants.ACTION_MENU_BIG) + || action.equals(SYSTEMUI_TASK_NO_ACTION)) { + return true; + } + return false; + } + + private static void launchActivity(Context context, Intent intent) { + try { + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + context.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); + } catch (Exception e) { + Log.i(TAG, "Unable to launch activity " + e); + } + } + + private static void switchToLastApp(Context context) { + final ActivityManager am = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.RunningTaskInfo lastTask = getLastTask(context, am); + + if (lastTask != null) { + am.moveTaskToFront(lastTask.id, ActivityManager.MOVE_TASK_NO_USER_ACTION, + getAnimation(context).toBundle()); + } + } + + private static ActivityOptions getAnimation(Context context) { + return ActivityOptions.makeCustomAnimation(context, + com.android.internal.R.anim.inv_app_in, + com.android.internal.R.anim.inv_app_out); + } + + private static ActivityManager.RunningTaskInfo getLastTask(Context context, + final ActivityManager am) { + final List packageNames = getCurrentLauncherPackages(context); + final List tasks = am.getRunningTasks(5); + for (int i = 1; i < tasks.size(); i++) { + String packageName = tasks.get(i).topActivity.getPackageName(); + if (!packageName.equals(context.getPackageName()) + && !packageName.equals(SYSTEMUI) + && !packageNames.contains(packageName)) { + return tasks.get(i); + } + } + return null; + } + + private static List getCurrentLauncherPackages(Context context) { + final PackageManager pm = context.getPackageManager(); + final List homeActivities = new ArrayList<>(); + pm.getHomeActivities(homeActivities); + final List packageNames = new ArrayList<>(); + for (ResolveInfo info : homeActivities) { + final String name = info.activityInfo.packageName; + if (!name.equals("com.android.settings")) { + packageNames.add(name); + } + } + return packageNames; + } + + private static void sendCloseSystemWindows(String reason) { + if (ActivityManagerNative.isSystemReady()) { + try { + ActivityManagerNative.getDefault().closeSystemDialogs(reason); + } catch (RemoteException e) { + } + } + } +/* + private static void toggleExpandedDesktop(Context context) { + ContentResolver cr = context.getContentResolver(); + String newVal = ""; + String currentVal = Settings.Global.getString(cr, Settings.Global.POLICY_CONTROL); + if (currentVal == null) { + currentVal = newVal; + } + if ("".equals(currentVal)) { + newVal = "immersive.full=*"; + } + Settings.Global.putString(cr, Settings.Global.POLICY_CONTROL, newVal); + if (newVal.equals("")) { + WindowManagerPolicyControl.reloadFromSetting(context); + } + } +*/ + private static void launchVoiceSearch(Context context) { + sendCloseSystemWindows("assist"); + // launch the search activity + Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + // TODO: This only stops the factory-installed search manager. + // Need to formalize an API to handle others + SearchManager searchManager = (SearchManager) context + .getSystemService(Context.SEARCH_SERVICE); + if (searchManager != null) { + searchManager.stopSearch(); + } + launchActivity(context, intent); + } catch (ActivityNotFoundException e) { + Slog.w(TAG, "No assist activity installed", e); + } + } + + private static void dispatchMediaKeyWithWakeLock(int keycode, Context context) { + if (ActivityManagerNative.isSystemReady()) { + KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), + SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, keycode, 0); + MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true); + event = KeyEvent.changeAction(event, KeyEvent.ACTION_UP); + MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true); + } + } + + private static void triggerVirtualKeypress(Context context, final int keyCode) { + final InputManager im = InputManager.getInstance(); + final long now = SystemClock.uptimeMillis(); + int downflags = 0; + + if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT + || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT + || keyCode == KeyEvent.KEYCODE_DPAD_UP + || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + downflags = KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE; + } else { + downflags = KeyEvent.FLAG_FROM_SYSTEM; + } + + final KeyEvent downEvent = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, + keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + downflags, InputDevice.SOURCE_KEYBOARD); + final KeyEvent upEvent = KeyEvent.changeAction(downEvent, KeyEvent.ACTION_UP); + final Handler handler = new Handler(Looper.getMainLooper()); + + final Runnable downRunnable = new Runnable() { + @Override + public void run() { + im.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + }; + + final Runnable upRunnable = new Runnable() { + @Override + public void run() { + im.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + }; + + handler.post(downRunnable); + handler.postDelayed(upRunnable, 10); + } + + private static void launchCamera(Context context) { + Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE_SECURE); + PackageManager pm = context.getPackageManager(); + final ResolveInfo mInfo = pm.resolveActivity(i, 0); + Intent intent = new Intent().setComponent(new ComponentName(mInfo.activityInfo.packageName, + mInfo.activityInfo.name)); + launchActivity(context, intent); + } + + private static void toggleWifi(Context context) { + WifiManager wfm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + wfm.setWifiEnabled(!wfm.isWifiEnabled()); + } + + private static void toggleBluetooth() { + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + boolean enabled = bluetoothAdapter.isEnabled(); + if (enabled) { + bluetoothAdapter.disable(); + } else { + bluetoothAdapter.enable(); + } + } + + private static void toggleWifiAP(Context context) { + final ContentResolver cr = context.getContentResolver(); + WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + final ConnectivityManager mConnectivityManager; + mConnectivityManager = (ConnectivityManager) context.getSystemService( + Context.CONNECTIVITY_SERVICE); + int state = wm.getWifiApState(); + boolean enabled = false; + switch (state) { + case WifiManager.WIFI_AP_STATE_ENABLING: + case WifiManager.WIFI_AP_STATE_ENABLED: + enabled = false; + break; + case WifiManager.WIFI_AP_STATE_DISABLING: + case WifiManager.WIFI_AP_STATE_DISABLED: + enabled = true; + break; + } + + // Turn on the Wifi AP + if (enabled) { + OnStartTetheringCallback callback = new OnStartTetheringCallback(); + mConnectivityManager.startTethering( + ConnectivityManager.TETHERING_WIFI, false, callback); + } else { + mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + } + } + + static final class OnStartTetheringCallback extends + ConnectivityManager.OnStartTetheringCallback { + @Override + public void onTetheringStarted() {} + @Override + public void onTetheringFailed() { + // TODO: Show error. + } + } + + private static void sendCommandToWindowManager(Intent intent) { + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); + try { + wm.sendCustomAction(intent); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + public static void killProcess(Context context) { + if (context.checkCallingOrSelfPermission( + android.Manifest.permission.FORCE_STOP_PACKAGES) == PackageManager.PERMISSION_GRANTED + && !isLockTaskOn()) { + try { + PackageManager packageManager = context.getPackageManager(); + final Intent intent = new Intent(Intent.ACTION_MAIN); + String defaultHomePackage = "com.android.launcher"; + intent.addCategory(Intent.CATEGORY_HOME); + final ResolveInfo res = packageManager.resolveActivity(intent, 0); + if (res.activityInfo != null + && !res.activityInfo.packageName.equals("android")) { + defaultHomePackage = res.activityInfo.packageName; + } + + // Use UsageStats to determine foreground app + UsageStatsManager usageStatsManager = (UsageStatsManager) context + .getSystemService(Context.USAGE_STATS_SERVICE); + long current = System.currentTimeMillis(); + long past = current - (1000 * 60 * 60); // uses snapshot of usage over past 60 + // minutes + + // Get the list, then sort it chronilogically so most recent usage is at start of + // list + List recentApps = usageStatsManager.queryUsageStats( + UsageStatsManager.INTERVAL_DAILY, past, current); + Collections.sort(recentApps, new Comparator() { + @Override + public int compare(UsageStats lhs, UsageStats rhs) { + long timeLHS = lhs.getLastTimeUsed(); + long timeRHS = rhs.getLastTimeUsed(); + if (timeLHS > timeRHS) { + return -1; + } else if (timeLHS < timeRHS) { + return 1; + } + return 0; + } + }); + + IActivityManager iam = ActivityManagerNative.getDefault(); + // this may not be needed due to !isLockTaskOn() in entry if + // if (am.getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE) return; + + // Look for most recent usagestat with lastevent == 1 and grab package name + // ...this seems to map to the UsageEvents.Event.MOVE_TO_FOREGROUND + String pkg = null; + for (int i = 0; i < recentApps.size(); i++) { + UsageStats mostRecent = recentApps.get(i); + if (mostRecent.mLastEvent == 1) { + pkg = mostRecent.mPackageName; + break; + } + } + + if (pkg != null && !pkg.equals("com.android.systemui") + && !pkg.equals(defaultHomePackage) && !isPackageLiveWalls(context, pkg)) { + + // Restore home screen stack before killing the app + Intent home = new Intent(Intent.ACTION_MAIN, null); + home.addCategory(Intent.CATEGORY_HOME); + home.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + context.startActivity(home); + + // Kill the app + iam.forceStopPackage(pkg, UserHandle.USER_CURRENT); + + // Remove killed app from Recents + final ParceledListSlice recentTasks = iam + .getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), + ActivityManager.RECENT_IGNORE_UNAVAILABLE, + UserHandle.CURRENT.getIdentifier()); + List recentList = recentTasks.getList(); + final int size = recentList.size(); + for (int i = 0; i < size; i++) { + ActivityManager.RecentTaskInfo recentInfo = recentList.get(i); + if (recentInfo.baseIntent.getComponent().getPackageName().equals(pkg)) { + int taskid = recentInfo.persistentId; + iam.removeTask(taskid); + } + } + + String pkgName; + try { + pkgName = (String) packageManager.getApplicationLabel( + packageManager.getApplicationInfo(pkg, + PackageManager.GET_META_DATA)); + } catch (PackageManager.NameNotFoundException e) { + // Just use pkg if issues getting appName + pkgName = pkg; + } + + Resources systemUIRes = ActionUtils.getResourcesForPackage(context, + ActionUtils.PACKAGE_SYSTEMUI); + int ident = systemUIRes.getIdentifier("app_killed_message", ActionUtils.STRING, + ActionUtils.PACKAGE_SYSTEMUI); + String toastMsg = systemUIRes.getString(ident, pkgName); + Context ctx = getPackageContext(context, ActionUtils.PACKAGE_SYSTEMUI); + Toast.makeText(ctx != null ? ctx : context, toastMsg, Toast.LENGTH_SHORT) + .show(); + return; + } else { + // make a "didnt kill anything" toast? + return; + } + } catch (RemoteException remoteException) { + Log.d("ActionHandler", "Caller cannot kill processes, aborting"); + } + } else { + Log.d("ActionHandler", "Caller cannot kill processes, aborting"); + } + } + + public static Context getPackageContext(Context context, String packageName) { + Context pkgContext = null; + if (context.getPackageName().equals(packageName)) { + pkgContext = context; + } else { + try { + pkgContext = context.createPackageContext(packageName, + Context.CONTEXT_IGNORE_SECURITY + | Context.CONTEXT_INCLUDE_CODE); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } + return pkgContext; + } + + private static boolean isPackageLiveWalls(Context ctx, String pkg) { + if (ctx == null || pkg == null) { + return false; + } + List liveWallsList = ctx.getPackageManager().queryIntentServices( + new Intent(WallpaperService.SERVICE_INTERFACE), + PackageManager.GET_META_DATA); + if (liveWallsList == null) { + return false; + } + for (ResolveInfo info : liveWallsList) { + if (info.serviceInfo != null) { + String packageName = info.serviceInfo.packageName; + if (TextUtils.equals(pkg, packageName)) { + return true; + } + } + } + return false; + } + + private static void screenOff(Context context) { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + pm.goToSleep(SystemClock.uptimeMillis()); + } + + private static void launchAssistAction(Context context) { + sendCloseSystemWindows("assist"); + Intent intent = ((SearchManager) context.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(true); + if (intent != null) { + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_SINGLE_TOP + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + try { + context.startActivityAsUser(intent, UserHandle.CURRENT); + } catch (ActivityNotFoundException e) { + Slog.w(TAG, "No activity to handle assist action.", e); + } + } + } + + // needed to prevent hwkey actions from killing a process while locked + public static boolean isLockTaskOn() { + try { + return ActivityManagerNative.getDefault().isInLockTaskMode(); + } catch (Exception e) { + } + return false; + } + + public static void volumePanel(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + am.adjustVolume(AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI); + } + +/* + private static void toggleOneHandedMode(Context context, String direction) { + String str = Settings.Global.getString(context.getContentResolver(), Settings.Global.SINGLE_HAND_MODE); + + if (TextUtils.isEmpty(str)) + Settings.Global.putString(context.getContentResolver(), Settings.Global.SINGLE_HAND_MODE, direction); + else + Settings.Global.putString(context.getContentResolver(), Settings.Global.SINGLE_HAND_MODE, ""); + } + */ + + public static void startAssistantSoundSearch(Context context) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setAction("com.google.android.googlequicksearchbox.MUSIC_SEARCH"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + context.startActivity(intent); + } +} diff --git a/core/java/com/android/internal/utils/ActionHolder.java b/core/java/com/android/internal/utils/ActionHolder.java new file mode 100644 index 000000000000..6d6c3aa926c9 --- /dev/null +++ b/core/java/com/android/internal/utils/ActionHolder.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 TeamEos project + * Author Randall Rushing aka bigrushdog, randall.rushing@gmail.com + * + * 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. + * + * Widgets may implement this interface to interact with action configurations + * + */ + +package com.android.internal.utils; + +import com.android.internal.utils.ActionConstants.ConfigMap; +import com.android.internal.utils.ActionConstants.Defaults; +import com.android.internal.utils.Config.ActionConfig; +import com.android.internal.utils.Config.ButtonConfig; + +public interface ActionHolder { + public String getTag(); + public void setTag(String tag); + public Defaults getDefaults(); + public void setDefaults(Defaults defaults); + public ConfigMap getConfigMap(); + public void setConfigMap(ConfigMap map); + public ButtonConfig getButtonConfig(); + public void setButtonConfig(ButtonConfig button); + public ActionConfig getActionConfig(); + public void setActionConfig(ActionConfig action); + public ButtonConfig getDefaultButtonConfig(); + public void setDefaultButtonConfig(ButtonConfig button); + public ActionConfig getDefaultActionConfig(); + public void setDefaultActionConfig(ActionConfig action); +} diff --git a/core/java/com/android/internal/utils/ActionUtils.java b/core/java/com/android/internal/utils/ActionUtils.java new file mode 100644 index 000000000000..d4207c25a7b9 --- /dev/null +++ b/core/java/com/android/internal/utils/ActionUtils.java @@ -0,0 +1,792 @@ +/* + * Copyright (C) 2014 The TeamEos 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. + * + * Helper functions mostly for device configuration and some utilities + * including a fun ViewGroup crawler and dpi conversion + * + */ + +package com.android.internal.utils; + +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +//import android.content.res.ThemeConfig; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +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.Bundle; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.Display; +import android.view.IWindowManager; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.WindowManagerGlobal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import com.android.internal.telephony.PhoneConstants; +import com.android.internal.utils.ActionConstants.Defaults; +import com.android.internal.utils.Config.ActionConfig; +import com.android.internal.utils.Config.ButtonConfig; + +public final class ActionUtils { + public static final String PACKAGE_SYSTEMUI = "com.android.systemui"; + public static final String PACKAGE_SETTINGS = "com.android.settings"; + public static final String CLASS_NAME_ICON_PICKER_GRID_ACTIVITY = "com.android.settings.smartnav.IconPackGridActivity"; + public static final String CLASS_NAME_ICON_PICKER_ACTIVITY = "com.android.settings.smartnav.IconPickerActivity"; + public static final String CLASS_NAME_ACTION_EDIT = "com.android.settings.smartnav.ActionPickerDialogActivity"; + public static final String CLASS_NAME_GALLERY_PICKER = "com.android.settings.smartnav.IconPickerGallery"; + public static final String PACKAGE_ANDROID = "android"; + public static final String INTENT_EXTRA_EXCLUDE_ACTIONS = "excluded_actions"; + public static final String INTENT_ACTION_ACTION_PICKER = "intent_action_action_picker"; + public static final String INTENT_EXTRA_RESULT = "result"; + public static final String INTENT_EXTRA_URI = "uri"; + public static final String INTENT_EXTRA_ACTION_STRING = "action_string"; + public static final String INTENT_EXTRA_ACTION_CONFIG = "action_config"; + public static final String INTENT_EXTRA_ACTION_DEFAULT = "default"; + public static final String INTENT_EXTRA_ACTION_HAS_DEFAULTS = "has_defaults"; + public static final String INTENT_EXTRA_ICON_PACKAGE_NAME = "icon_package_name"; + public static final String INTENT_EXTRA_ICON_DATA_TYPE = "icon_data_type"; + public static final String INTENT_EXTRA_ICON_DATA_TYPE_ICON_PACK = "iconpack"; + public static final String INTENT_EXTRA_ICON_DATA_PACKAGE = "icon_data_package"; + public static final String INTENT_EXTRA_ICON_DATA_NAME = "icon_data_name"; + public static final String INTENT_ICON_PICKER = "intent_icon_picker"; + public static final String INTENT_GALLERY_PICKER = "intent_gallery_picker"; + public static final String INTENT_NAVBAR_EDIT_RESET_LAYOUT = "intent_navbar_edit_reset_layout"; + + public static final String ANDROIDNS = "http://schemas.android.com/apk/res/android"; + public static final String FORMAT_NONE = "none"; + public static final String FORMAT_FLOAT = "float"; + + public static final String ID = "id"; + public static final String DIMEN = "dimen"; + public static final String DIMEN_PIXEL = "dimen_pixel"; + public static final String FLOAT = "float"; + public static final String INT = "integer"; + public static final String DRAWABLE = "drawable"; + public static final String COLOR = "color"; + public static final String BOOL = "bool"; + public static final String STRING = "string"; + public static final String ANIM = "anim"; + + public static final int SMARTNAV_ICON_MAX_WIDTH = 512; + public static final int SMARTNAV_ICON_MAX_HEIGHT = 512; + + // 10 inch tablets + public static boolean isXLargeScreen() { + int screenLayout = Resources.getSystem().getConfiguration().screenLayout & + Configuration.SCREENLAYOUT_SIZE_MASK; + return screenLayout == Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + + // 7 inch "phablets" i.e. grouper + public static boolean isLargeScreen() { + int screenLayout = Resources.getSystem().getConfiguration().screenLayout & + Configuration.SCREENLAYOUT_SIZE_MASK; + return screenLayout == Configuration.SCREENLAYOUT_SIZE_LARGE; + } + + // normal phones + public static boolean isNormalScreen() { + int screenLayout = Resources.getSystem().getConfiguration().screenLayout & + Configuration.SCREENLAYOUT_SIZE_MASK; + return screenLayout == Configuration.SCREENLAYOUT_SIZE_NORMAL; + } + + public static boolean isLandscape(Context context) { + return Configuration.ORIENTATION_LANDSCAPE + == context.getResources().getConfiguration().orientation; + } + + public static boolean navigationBarCanMove() { + return Resources.getSystem().getConfiguration().smallestScreenWidthDp < 600; + } + + public static boolean hasNavbarByDefault(Context context) { + boolean needsNav = (Boolean)getValue(context, "config_showNavigationBar", BOOL, PACKAGE_ANDROID); + String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); + if ("1".equals(navBarOverride)) { + needsNav = false; + } else if ("0".equals(navBarOverride)) { + needsNav = true; + } + return needsNav; + } + + 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; + return tm.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE; + } + + 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 = (String) getValue(context, "config_dozeComponent", + STRING, PACKAGE_ANDROID); + return !TextUtils.isEmpty(name); + } + + /** + * This method converts dp unit to equivalent pixels, depending on device + * density. + * + * @param dp A value in dp (density independent pixels) unit. Which we need + * to convert into pixels + * @param context Context to get resources and device specific display + * metrics + * @return A float value to represent px equivalent to dp depending on + * device density + */ + public static float convertDpToPixel(float dp, Context context) { + Resources resources = context.getResources(); + DisplayMetrics metrics = resources.getDisplayMetrics(); + float px = dp * (metrics.densityDpi / 160f); + return px; + } + + public static int ConvertDpToPixelAsInt(float dp, Context context) { + float px = convertDpToPixel(dp, context); + if (px < 1) + px = 1; + return Math.round(px); + } + + public static int ConvertDpToPixelAsInt(int dp, Context context) { + float px = convertDpToPixel((float) dp, context); + if (px < 1) + px = 1; + return Math.round(px); + } + + /** + * This method converts device specific pixels to density independent + * pixels. + * + * @param px A value in px (pixels) unit. Which we need to convert into db + * @param context Context to get resources and device specific display + * metrics + * @return A float value to represent dp equivalent to px value + */ + public static float convertPixelsToDp(float px, Context context) { + Resources resources = context.getResources(); + DisplayMetrics metrics = resources.getDisplayMetrics(); + float dp = px / (metrics.densityDpi / 160f); + return dp; + } + + public static int dpToPx(Context context, int dp) { + return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5); + } + + public static int pxToDp(Context context, int px) { + return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5); + } + + /* utility to iterate a viewgroup and return a list of child views */ + public static ArrayList getAllChildren(View v) { + + if (!(v instanceof ViewGroup)) { + ArrayList viewArrayList = new ArrayList(); + viewArrayList.add(v); + return viewArrayList; + } + + ArrayList result = new ArrayList(); + + ViewGroup vg = (ViewGroup) v; + for (int i = 0; i < vg.getChildCount(); i++) { + + View child = vg.getChildAt(i); + + ArrayList viewArrayList = new ArrayList(); + viewArrayList.add(v); + viewArrayList.addAll(getAllChildren(child)); + + result.addAll(viewArrayList); + } + return result; + } + + /* utility to iterate a viewgroup and return a list of child views of type */ + public static ArrayList getAllChildren(View root, Class returnType) { + if (!(root instanceof ViewGroup)) { + ArrayList viewArrayList = new ArrayList(); + try { + viewArrayList.add(returnType.cast(root)); + } catch (Exception e) { + // handle all exceptions the same and silently fail + } + return viewArrayList; + } + ArrayList result = new ArrayList(); + ViewGroup vg = (ViewGroup) root; + for (int i = 0; i < vg.getChildCount(); i++) { + View child = vg.getChildAt(i); + ArrayList viewArrayList = new ArrayList(); + try { + viewArrayList.add(returnType.cast(root)); + } catch (Exception e) { + // handle all exceptions the same and silently fail + } + viewArrayList.addAll(getAllChildren(child, returnType)); + result.addAll(viewArrayList); + } + return result; + } + + public static void resolveAndUpdateButtonActions(Context ctx, Defaults defaults) { + if (ctx == null || defaults == null) { + return; + } + boolean configChanged = false; + final PackageManager pm = ctx.getPackageManager(); + ArrayList configs = Config.getConfig(ctx, defaults); + ArrayList buttonsToChange = new ArrayList(); + buttonsToChange.addAll(configs); + for (int h = 0; h < configs.size(); h++) { + ButtonConfig button = configs.get(h); + for (int i = 0; i < 3; i++) { + ActionConfig action = button.getActionConfig(i); + final String task = action.getAction(); + if (task.startsWith(ActionHandler.SYSTEM_PREFIX)) { + continue; + } + String resolvedName = getFriendlyNameForUri(ctx, task); + if (resolvedName == null || TextUtils.equals(resolvedName, task)) { + // if resolved name is null or the full raw intent string is + // returned, we were unable to resolve + configChanged = true; + ActionConfig newAction = new ActionConfig(ctx, + ActionHandler.SYSTEMUI_TASK_NO_ACTION, action.getIconUri()); + ButtonConfig newButton = buttonsToChange.get(h); + newButton.setActionConfig(newAction, i); + buttonsToChange.remove(h); + buttonsToChange.add(h, newButton); + } + } + } + if (configChanged) { + Config.setConfig(ctx, defaults, buttonsToChange); + } + } + + public static Intent getIntent(String uri) { + if (uri == null || uri.startsWith(ActionHandler.SYSTEM_PREFIX)) { + return null; + } + + Intent intent = null; + try { + intent = Intent.parseUri(uri, 0); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + return intent; + } + + public static Object getValue(Context context, String resName, String resType, String pkg) { + return getValue(context, resName, resType, null, pkg); + } + + public static Object getValue(Context context, String resName, String resType, String format, + String pkg) { + Resources res = getResourcesForPackage(context, pkg); + String tmp; + if (resType.equals(DIMEN_PIXEL)) { + tmp = DIMEN; + } else { + tmp = resType; + } + int id = res.getIdentifier(resName, tmp, pkg); + if (format != null) { // standard res + TypedValue typedVal = new TypedValue(); + res.getValue(id, typedVal, true); + if (format.equals(FORMAT_FLOAT)) { + return Float.valueOf(typedVal.getFloat()); + } + } else { // typed values + if (resType.equals(ID)) { + return Integer.valueOf(id); + } else if (resType.equals(DIMEN)) { + return Float.valueOf(res.getDimension(id)); + } else if (resType.equals(DIMEN_PIXEL)) { + return Integer.valueOf(res.getDimensionPixelSize(id)); + } else if (resType.equals(FLOAT)) { + return Float.valueOf(res.getFloat(id)); + } else if (resType.equals(INT)) { + return Integer.valueOf(res.getInteger(id)); + } else if (resType.equals(COLOR)) { + int rawColor = res.getColor(id); + return Integer.valueOf(Color.argb(Color.alpha(rawColor), Color.red(rawColor), + Color.green(rawColor), Color.blue(rawColor))); + } else if (resType.equals(BOOL)) { + return Boolean.valueOf(res.getBoolean(id)); + } else if (resType.equals(STRING)) { + return String.valueOf(res.getString(id)); + } else if (resType.equals(DRAWABLE)) { + return getDrawable(context, resName, pkg); + } + } + return null; + } + + public static void putValue(String key, Object val, String type, Bundle b) { + if (type.equals(ID) || type.equals(DIMEN_PIXEL) || type.equals(INT) || type.equals(COLOR)) { + b.putInt(key, (Integer) val); + } else if (type.equals(FLOAT) || type.equals(DIMEN)) { + b.putFloat(key, (Float) val); + } else if (type.equals(BOOL)) { + b.putBoolean(key, (Boolean) val); + } else if (type.equals(STRING)) { + b.putString(key, (String) val); + } + } + + public static int getIdentifier(Context context, String resName, String resType, String pkg) { + try { + Resources res = context.getPackageManager() + .getResourcesForApplication(pkg); + int ident = res.getIdentifier(resName, resType, pkg); + return ident; + } catch (Exception e) { + return -1; + } + } + + public static String getString(Context context, String resName, String pkg) { + return (String) getValue(context, resName, STRING, null, pkg); + } + + public static boolean getBoolean(Context context, String resName, String pkg) { + return (Boolean) getValue(context, resName, BOOL, null, pkg); + } + + public static int getInt(Context context, String resName, String pkg) { + return (Integer) getValue(context, resName, INT, null, pkg); + } + + public static int getColor(Context context, String resName, String pkg) { + return (Integer) getValue(context, resName, COLOR, null, pkg); + } + + public static int getId(Context context, String resName, String pkg) { + return (Integer) getValue(context, resName, ID, null, pkg); + } + + public static float getDimen(Context context, String resName, String pkg) { + return (Float) getValue(context, resName, DIMEN, null, pkg); + } + + public static int getDimenPixelSize(Context context, String resName, String pkg) { + return (Integer) getValue(context, resName, DIMEN_PIXEL, null, pkg); + } + + public static Drawable getDrawable(Context context, String drawableName, String pkg) { + return getDrawable(getResourcesForPackage(context, pkg), drawableName, pkg); + } + + public static Drawable getDrawable(Context context, Uri uri) { + //set inputs here so we can clean up them in the finally + InputStream inputStream = null; + + try { + //get the inputstream + inputStream = context.getContentResolver().openInputStream(uri); + + //get available bitmapfactory options + BitmapFactory.Options options = new BitmapFactory.Options(); + //query the bitmap to decode the stream but don't allocate pixels in memory yet + options.inJustDecodeBounds = true; + //decode the bitmap with calculated bounds + Bitmap b1 = BitmapFactory.decodeStream(inputStream, null, options); + //get raw height and width of the bitmap + int rawHeight = options.outHeight; + int rawWidth = options.outWidth; + + //check if the bitmap is big and we need to scale the quality to take less memory + options.inSampleSize = calculateInSampleSize(options, rawHeight, rawWidth); + + //We need to close and load again the inputstream to avoid null + try { + inputStream.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + inputStream = context.getContentResolver().openInputStream(uri); + + //decode the stream again, with the calculated SampleSize option, + //and allocate the memory. Also add some metrics options to take a proper density + options.inJustDecodeBounds = false; + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + options.inScreenDensity = metrics.densityDpi; + options.inTargetDensity = metrics.densityDpi; + options.inDensity = DisplayMetrics.DENSITY_DEFAULT; + b1 = BitmapFactory.decodeStream(inputStream, null, options); + return new BitmapDrawable(context.getResources(), b1); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + //clean up the system resources + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + //Automate the quality scaling process + public static int calculateInSampleSize(BitmapFactory.Options options, int height, int width) { + //set default inSampleSize scale factor (no scaling) + int inSampleSize = 1; + + //if img size is in 257-512 range, sample scale factor will be 4x + if (height > 256 || width > 256) { + inSampleSize = 4; + return inSampleSize; + //if img size is in 129-256 range, sample scale factor will be 2x + } else if (height > 128 || width > 128) { + inSampleSize = 2; + return inSampleSize; + } + //if img size is in 0-128 range, no need to scale it + return inSampleSize; + } + + /** + * Screen images based on desired dimensions before fully decoding + * + *@param ctx Calling context + *@param uri Image uri + *@param maxWidth maximum allowed image width + *@param maxHeight maximum allowed image height + */ + public static boolean isBitmapAllowedSize(Context ctx, Uri uri, int maxWidth, int maxHeight) { + InputStream inputStream = null; + try { + inputStream = ctx.getContentResolver().openInputStream(uri); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeStream(inputStream, null, options); + if (options.outWidth <= maxWidth && options.outHeight <= maxHeight) { + return true; + } + } catch (Exception e) { + return false; + } finally { + try { + inputStream.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + return false; + } + + public static Drawable getDrawableFromComponent(PackageManager pm, String activity) { + Drawable d = null; + try { + Intent intent = Intent.parseUri(activity, 0); + ActivityInfo info = intent.resolveActivityInfo(pm, + PackageManager.GET_ACTIVITIES); + if (info != null) { + d = info.loadIcon(pm); + } + } catch (Exception e) { + e.printStackTrace(); + } + return d; + } + + public static String getFriendlyActivityName(PackageManager pm, Intent intent, + boolean labelOnly) { + ActivityInfo ai = intent.resolveActivityInfo(pm, PackageManager.GET_ACTIVITIES); + String friendlyName = null; + if (ai != null) { + friendlyName = ai.loadLabel(pm).toString(); + if (friendlyName == null && !labelOnly) { + friendlyName = ai.name; + } + } + return friendlyName != null || labelOnly ? friendlyName : intent.toUri(0); + } + + public static String getFriendlyShortcutName(PackageManager pm, Intent intent) { + String activityName = getFriendlyActivityName(pm, intent, true); + String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); + + if (activityName != null && name != null) { + return activityName + ": " + name; + } + return name != null ? name : intent.toUri(0); + } + + public static String getFriendlyNameForUri(Context ctx, String uri) { + if (uri == null) { + return null; + } + if (uri.startsWith(ActionHandler.SYSTEM_PREFIX)) { + for (int i = 0; i < ActionHandler.systemActions.length; i++) { + if (ActionHandler.systemActions[i].mAction.equals(uri)) { + return getString(ctx, ActionHandler.systemActions[i].mLabelRes, + ActionHandler.systemActions[i].mResPackage); + } + } + } else { + try { + Intent intent = Intent.parseUri(uri, 0); + if (Intent.ACTION_MAIN.equals(intent.getAction())) { + return getFriendlyActivityName(ctx.getPackageManager(), intent, false); + } + return getFriendlyShortcutName(ctx.getPackageManager(), intent); + } catch (URISyntaxException e) { + } + } + return uri; + } + + public static boolean isPackageInstalled(Context ctx, String packageName) { + try { + PackageInfo info = ctx.getPackageManager() + .getPackageInfo(packageName, PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + return true; + } + + /** + * + * @param Target package resources + * @param drawableName + * @param Target package name + * @return the drawable if found, otherwise fall back to a green android guy + */ + public static Drawable getDrawable(Resources res, String drawableName, String pkg) { + try { + int resId = res.getIdentifier(drawableName, DRAWABLE, pkg); + Drawable icon = ImageHelper.getVector(res, resId, false); + if (icon == null) { + icon = res.getDrawable(resId); + } + return icon; + } catch (Exception e) { + return res.getDrawable( + com.android.internal.R.drawable.sym_def_app_icon); + } + } + + /** + * + * @param Target package resources + * @param drawableName + * @param Target package name + * @return the drawable if found, null otherwise. Useful for testing if a drawable is found + * in a theme overlay + */ + private static Drawable getMaybeNullDrawable(Resources res, String drawableName, String pkg) { + try { + int resId = res.getIdentifier(drawableName, DRAWABLE, pkg); + Drawable icon = ImageHelper.getVector(res, resId, false); + if (icon == null) { + icon = res.getDrawable(resId); + } + return icon; + } catch (Exception e) { + return null; + } + } + + public static Resources getResourcesForPackage(Context ctx, String pkg) { + try { + Resources res = ctx.getPackageManager() + .getResourcesForApplication(pkg); + return res; + } catch (Exception e) { + return ctx.getResources(); + } + } + + /** + * + * @param Context of the calling package + * @param the action we want a drawable for + * @return if a system action drawable is requested, we try to get the drawable + * from any current navigation overlay. if no overlay is found, get it + * from SystemUI. Return a component drawable if not a system action + */ + public static Drawable getDrawableForAction(Context context, String action) { + Drawable d = null; + + // this null check is probably no-op but let's be safe anyways + if (action == null || context == null) { + return d; + } + if (action.startsWith(ActionHandler.SYSTEM_PREFIX)) { + for (int i = 0; i < ActionHandler.systemActions.length; i++) { + if (ActionHandler.systemActions[i].mAction.equals(action)) { + // should always be SystemUI + String packageName = ActionHandler.systemActions[i].mResPackage; + Resources res = getResourcesForPackage(context, packageName); + String iconName = ActionHandler.systemActions[i].mIconRes; + d = getNavbarThemedDrawable(context, res, iconName); + if (d == null) { + d = getDrawable(res, iconName, packageName); + } + } + } + } else { + d = getDrawableFromComponent(context.getPackageManager(), action); + } + return d; + } + + /** + * + * @param calling package context, usually Settings for the custom action list adapter + * @param target package resources, usually SystemUI + * @param drawableName + * @return a navigation bar overlay themed action drawable if available, otherwise + * return drawable from SystemUI resources + */ + public static Drawable getNavbarThemedDrawable(Context context, Resources defRes, + String drawableName) { + if (context == null || defRes == null || drawableName == null) + return null; + + // TODO: turn on cmte support when it comes back + return getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI); +/* + ThemeConfig themeConfig = context.getResources().getConfiguration().themeConfig; + + Drawable d = null; + if (themeConfig != null) { + try { + final String navbarThemePkgName = themeConfig.getOverlayForNavBar(); + final String sysuiThemePkgName = themeConfig.getOverlayForStatusBar(); + // Check if the same theme is applied for systemui, if so we can skip this + if (navbarThemePkgName != null && !navbarThemePkgName.equals(sysuiThemePkgName)) { + // Navbar theme and SystemUI (statusbar) theme packages are different + // But we can't assume navbar package has our drawable, so try navbar theme + // package first. If we fail, try the systemui (statusbar) package + // if we still fail, fall back to default package resource + Resources res = context.getPackageManager().getThemedResourcesForApplication( + PACKAGE_SYSTEMUI, navbarThemePkgName); + d = getMaybeNullDrawable(res, drawableName, PACKAGE_SYSTEMUI); + if (d == null) { + // drawable not found in overlay, get from default SystemUI res + d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI); + } + } else { + // no navbar overlay present, get from default SystemUI res + d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI); + } + } catch (PackageManager.NameNotFoundException e) { + // error thrown (unlikely), get from default SystemUI res + d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI); + } + } + if (d == null) { + // theme config likely null, get from default SystemUI res + d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI); + } + return d; + */ + } +} diff --git a/core/java/com/android/internal/utils/Config.java b/core/java/com/android/internal/utils/Config.java new file mode 100644 index 000000000000..271e2bba6499 --- /dev/null +++ b/core/java/com/android/internal/utils/Config.java @@ -0,0 +1,585 @@ +/* + * Copyright (C) 2015 TeamEos project + * Author Randall Rushing aka bigrushdog, randall.rushing@gmail.com + * + * 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. + * + * Config.java: A helper class for loading/setting feature button configurations + * to SettingsProvider. We start with defining a "action" in the nested + * ActionConfig class. A action holds a raw action string, a label for that action, + * and helper functions for loading an associated drawable for that action. + * + * The nested static class ButtonConfig is a convenience class that holds three + * ActionConfig objects. Those ActionConfig objects are labeled as "PRIMARY", + * "SECOND", and "THIRD", which will typically refer to a single tap, long press, + * and double tap, respectively. However, this is not always the case, thus the + * more generalized naming convention. + * + * ActionConfig and ButtonConfig implement the private Stringable interface to allow + * for easy loading and setting + * + */ +package com.android.internal.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.android.internal.utils.ActionHandler; +import com.android.internal.utils.ActionConstants.ConfigMap; +import com.android.internal.utils.ActionConstants.Defaults; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.UserHandle; +import android.provider.Settings; +import android.text.TextUtils; + +public class Config { + private interface Stringable { + public String toDelimitedString(); + public void fromList(Context ctx, List items); + } + + /** + * For use with action/button based features that don't require a defaut configuration + */ + public static ArrayList getConfig(Context ctx, String uri, + boolean fromSecureSettings) { + if (ctx == null || uri == null) { + return null; + } + String config; + if (fromSecureSettings) { + config = Settings.Secure.getStringForUser( + ctx.getContentResolver(), uri, + UserHandle.USER_CURRENT); + } else { + config = Settings.System.getStringForUser( + ctx.getContentResolver(), uri, + UserHandle.USER_CURRENT); + } + if (TextUtils.isEmpty(config)) { + return null; + } + ArrayList items = new ArrayList(); + items.addAll(Arrays.asList(config.split("\\|"))); // split string into array elements + int numConfigs = Integer.parseInt(items.get(0)); // first element is always the number of + // ButtonConfigs to parse + items.remove(0); // remove button count for a clean list of buttons + + ArrayList buttonList = new ArrayList(); + ButtonConfig buttonConfig; + + for (int i = 0; i < numConfigs; i++) { + int from = i * ButtonConfig.NUM_ELEMENTS; // (0, 10), (10, 20)... + int to = from + ButtonConfig.NUM_ELEMENTS; + buttonConfig = new ButtonConfig(ctx); + buttonConfig.fromList(ctx, items.subList(from, to)); // initialize button from list + // elements + buttonList.add(buttonConfig); + } + return buttonList; + } + + public static ArrayList getConfig(Context ctx, Defaults defaults) { + if (ctx == null || defaults == null) { + return null; + } + String config = Settings.Secure.getStringForUser( + ctx.getContentResolver(), defaults.getUri(), + UserHandle.USER_CURRENT); + if (TextUtils.isEmpty(config)) { + config = defaults.getDefaultConfig(); + } + + ArrayList items = new ArrayList(); + items.addAll(Arrays.asList(config.split("\\|"))); // split string into array elements + int numConfigs = Integer.parseInt(items.get(0)); // first element is always the number of ButtonConfigs to parse + items.remove(0); // remove button count for a clean list of buttons + + ArrayList buttonList = new ArrayList(); + ButtonConfig buttonConfig; + + for (int i = 0; i < numConfigs; i++) { + int from = i * ButtonConfig.NUM_ELEMENTS; // (0, 10), (10, 20)... + int to = from + ButtonConfig.NUM_ELEMENTS; + buttonConfig = new ButtonConfig(ctx); + buttonConfig.fromList(ctx, items.subList(from, to)); // initialize button from list elements + buttonList.add(buttonConfig); + } + return buttonList; + } + + public static ArrayList getDefaultConfig(Context ctx, Defaults defaults) { + if (ctx == null || defaults == null) { + return null; + } + String config = defaults.getDefaultConfig(); + ArrayList items = new ArrayList(); + items.addAll(Arrays.asList(config.split("\\|"))); + int numConfigs = Integer.parseInt(items.get(0)); + items.remove(0); + ArrayList buttonList = new ArrayList(); + ButtonConfig buttonConfig; + + for (int i = 0; i < numConfigs; i++) { + int from = i * ButtonConfig.NUM_ELEMENTS; + int to = from + ButtonConfig.NUM_ELEMENTS; + buttonConfig = new ButtonConfig(ctx); + buttonConfig.fromList(ctx, items.subList(from, to)); + buttonList.add(buttonConfig); + } + return buttonList; + } + + public static void setConfig(Context ctx, Defaults defaults, ArrayList config) { + if (ctx == null || defaults == null || config == null) { + return; + } + int numConfigs = config.size(); + if (numConfigs <= 0) { + return; + } + StringBuilder b = new StringBuilder(); + b.append(String.valueOf(numConfigs)); + b.append(ActionConstants.ACTION_DELIMITER); // size of list is always first element + for (ButtonConfig button : config) { + b.append(button.toDelimitedString()); // this is just beautiful ;D + } + String s = b.toString(); + if (s.endsWith(ActionConstants.ACTION_DELIMITER)) { + s = removeLastChar(s); // trim final delimiter if need be + } + Settings.Secure.putStringForUser(ctx.getContentResolver(), defaults.getUri(), s, + UserHandle.USER_CURRENT); + } + + public static ButtonConfig getButtonConfigFromTag(ArrayList configs, String tag) { + if (configs == null || tag == null) { + return null; + } + ButtonConfig config = null; + for (ButtonConfig b : configs) { + if (TextUtils.equals(b.getTag(), tag)) { + config = b; + break; + } + } + return config; + } + + public static ArrayList replaceButtonAtPosition(ArrayList configs, + ButtonConfig button, ConfigMap map) { + if (configs == null || button == null || map == null) { + return null; + } + configs.remove(map.button); + configs.add(map.button, button); + return configs; + } + + public static String removeLastChar(String s) { + if (s == null || s.length() == 0) { + return s; + } + return s.substring(0, s.length() - 1); + } + + public static class ButtonConfig implements Stringable, Parcelable { + public static final int NUM_ELEMENTS = 10; + protected ActionConfig[] configs = new ActionConfig[3]; + private String tag = ActionConstants.EMPTY; + + // internal use only + private ButtonConfig() { + } + + public ButtonConfig(Context ctx) { + configs[ActionConfig.PRIMARY] = new ActionConfig(ctx); + configs[ActionConfig.SECOND] = new ActionConfig(ctx); + configs[ActionConfig.THIRD] = new ActionConfig(ctx); + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public boolean hasCustomIcon() { + return configs[ActionConfig.PRIMARY].hasCustomIcon(); + } + + public void clearCustomIconIconUri() { + configs[ActionConfig.PRIMARY].clearCustomIconIconUri(); + } + + public void setCustomIconUri(String type, String packageName, String iconName) { + configs[ActionConfig.PRIMARY].setCustomIconUri(type, packageName, iconName); + } + + public void setCustomImageUri(Uri uri) { + configs[ActionConfig.PRIMARY].setCustomImageUri(uri); + } + + public Drawable getDefaultIcon(Context ctx) { + return configs[ActionConfig.PRIMARY].getDefaultIcon(ctx); + } + + public Drawable getCurrentIcon(Context ctx) { + return configs[ActionConfig.PRIMARY].getCurrentIcon(ctx); + } + + public boolean isSystemAction() { + return configs[ActionConfig.PRIMARY].isSystemAction(); + } + + public String getSystemActionIconName() { + return configs[ActionConfig.PRIMARY].getSystemActionIconName(); + } + + public ActionConfig getActionConfig(int which) { + if (which < ActionConfig.PRIMARY || which > ActionConfig.THIRD) { + return null; + } + return configs[which]; + } + + public void setActionConfig(ActionConfig config, int which) { + if (which < ActionConfig.PRIMARY || which > ActionConfig.THIRD || config == null) { + return; + } + configs[which] = config; + } + + public static void setButton(Context ctx, ButtonConfig button, String uri, boolean isSecure) { + StringBuilder b = new StringBuilder(); + b.append(button.toDelimitedString()); // this is just beautiful ;D + String s = b.toString(); + if (s.endsWith(ActionConstants.ACTION_DELIMITER)) { + s = removeLastChar(s); // trim final delimiter if need be + } + + if (isSecure) { + Settings.Secure.putStringForUser(ctx.getContentResolver(), uri, s, + UserHandle.USER_CURRENT); + } else { + Settings.System.putStringForUser(ctx.getContentResolver(), uri, s, + UserHandle.USER_CURRENT); + } + } + + public static ButtonConfig getButton(Context ctx, String uri, boolean isSecure) { + if (ctx == null || TextUtils.isEmpty(uri)) { + return null; + } + String config; + if (isSecure) { + config = Settings.Secure.getStringForUser( + ctx.getContentResolver(), uri, + UserHandle.USER_CURRENT); + } else { + config = Settings.System.getStringForUser( + ctx.getContentResolver(), uri, + UserHandle.USER_CURRENT); + } + if (TextUtils.isEmpty(config)) { + return new ButtonConfig(ctx); + } + ArrayList items = new ArrayList(); + items.addAll(Arrays.asList(config.split("\\|"))); + ButtonConfig buttonConfig = new ButtonConfig(ctx); + buttonConfig.fromList(ctx, items.subList(0, NUM_ELEMENTS)); // initialize button from + // list elements + return buttonConfig; + } + + @Override + public String toDelimitedString() { + return tag + ActionConstants.ACTION_DELIMITER + + configs[ActionConfig.PRIMARY].toDelimitedString() + + configs[ActionConfig.SECOND].toDelimitedString() + + configs[ActionConfig.THIRD].toDelimitedString(); + } + + @Override + public void fromList(Context ctx, List items) { + ArrayList buttons = new ArrayList(); + buttons.addAll(items); + tag = buttons.get(0); + + ActionConfig config = new ActionConfig(); + config.fromList(ctx, buttons.subList(1, 4)); + configs[ActionConfig.PRIMARY] = config; + + config = new ActionConfig(); + config.fromList(ctx, buttons.subList(4, 7)); + configs[ActionConfig.SECOND] = config; + + config = new ActionConfig(); + config.fromList(ctx, buttons.subList(7, 10)); + configs[ActionConfig.THIRD] = config; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(tag); + dest.writeParcelable(configs[ActionConfig.PRIMARY], flags); + dest.writeParcelable(configs[ActionConfig.SECOND], flags); + dest.writeParcelable(configs[ActionConfig.THIRD], flags); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public ButtonConfig createFromParcel(Parcel in) { + return new ButtonConfig(in); + } + + public ButtonConfig[] newArray(int size) { + return new ButtonConfig[size]; + } + }; + + private ButtonConfig(Parcel in) { + tag = in.readString(); + configs[ActionConfig.PRIMARY] = (ActionConfig) in.readParcelable(Config.ActionConfig.class + .getClassLoader()); + configs[ActionConfig.SECOND] = (ActionConfig) in.readParcelable(Config.ActionConfig.class + .getClassLoader()); + configs[ActionConfig.THIRD] = (ActionConfig) in.readParcelable(Config.ActionConfig.class + .getClassLoader()); + } + } + + public static class ActionConfig implements Stringable, Comparable, Parcelable { + public static final int PRIMARY = 0; + public static final int SECOND = 1; + public static final int THIRD = 2; + + private String action = ActionHandler.SYSTEMUI_TASK_NO_ACTION; + private String label = ActionConstants.EMPTY; + private String iconUri = ActionConstants.EMPTY; + + // internal use only + private ActionConfig() { + } + + public static ActionConfig create(Context ctx) { + return new ActionConfig(ctx); + } + + public static ActionConfig create(Context ctx, String action) { + return new ActionConfig(ctx, action); + } + + public static ActionConfig create(Context ctx, String action, String iconUri) { + return new ActionConfig(ctx, action, iconUri); + } + + public static String getActionFromDelimitedString(Context ctx, String delimited) { + ActionConfig actionConfig = new ActionConfig(ctx); + actionConfig.fromDelimitedString(delimited); + return actionConfig.action; + } + + public static String getActionFromDelimitedString(Context ctx, String delimited, + String defaultAction) { + if (delimited == null) { + return defaultAction; + } + return getActionFromDelimitedString(ctx, delimited); + } + + public ActionConfig(Context ctx) { + label = ActionUtils.getFriendlyNameForUri(ctx, action); + } + + public ActionConfig(Context ctx, String action) { + this.action = action; + label = ActionUtils.getFriendlyNameForUri(ctx, action); + } + + public ActionConfig(Context ctx, String action, String iconUri) { + this(ctx, action); + this.iconUri = iconUri; + } + + public String getAction() { + return action; + } + + public String getLabel() { + return label; + } + + public String getIconUri() { + if (!hasCustomIcon()) { + return action; + } else { + return iconUri; + } + } + + public boolean hasCustomIcon() { + return !TextUtils.equals(ActionConstants.EMPTY, iconUri); + } + + public void clearCustomIconIconUri() { + iconUri = ActionConstants.EMPTY; + } + + public boolean isSystemAction() { + return action.startsWith(ActionHandler.SYSTEM_PREFIX); + } + + public String getSystemActionIconName() { + if (action.startsWith(ActionHandler.SYSTEM_PREFIX)) { + for (int i = 0; i < ActionHandler.systemActions.length; i++) { + if (ActionHandler.systemActions[i].mAction.equals(action)) { + return ActionHandler.systemActions[i].mIconRes; + } + } + } + return null; + } + + public void setCustomImageUri(Uri uri) { + iconUri = "image$" + uri.toString(); + } + + public void setCustomIconUri(String type, String packageName, String iconName) { + StringBuilder b = new StringBuilder() + .append(type) + .append("$") + .append(packageName) + .append("$") + .append(iconName); + iconUri = b.toString(); + } + + public Drawable getDefaultIcon(Context ctx) { + return ActionUtils.getDrawableForAction(ctx, action); + } + + /** + * Returns custom icon (if exists) + * @param ctx app's context + * @return drawable when custom icon exists, null otherwise + */ + public Drawable getCurrentCustomIcon(Context ctx) { + if (hasCustomIcon()) { + List items = Arrays.asList(iconUri.split("\\$")); + String type = items.get(0); + if (type.equals("iconpack") && items.size() == 3) { + String packageName = items.get(1); + String iconName = items.get(2); + return ActionUtils.getDrawable(ctx, iconName, packageName); + } else if (type.equals("image") && items.size() == 2) { + String uri = items.get(1); + return ActionUtils.getDrawable(ctx, Uri.parse(uri)); + } + } + return null; + } + + public Drawable getCurrentIcon(Context ctx) { + + Drawable drawable = getCurrentCustomIcon(ctx); + + //If icon doesn't exist (or is not set) fallback to action one + if (drawable == null) { + drawable = ActionUtils.getDrawableForAction(ctx, action); + } + + return drawable; + + } + + public boolean hasNoAction() { + return TextUtils.equals(action, ActionHandler.SYSTEMUI_TASK_NO_ACTION) + || TextUtils.equals(action, ActionConstants.EMPTY); + } + + public boolean isActionRecents() { + return TextUtils.equals(action, ActionHandler.SYSTEMUI_TASK_RECENTS); + } + + public void fromDelimitedString(String delimited) { + ArrayList items = new ArrayList(); + items.addAll(Arrays.asList(delimited.split("\\|"))); + action = items.get(0); + label = items.get(1); + iconUri = items.get(2); + } + + @Override + public int compareTo(ActionConfig another) { + int result = label.toString().compareToIgnoreCase(another.label.toString()); + return result; + } + + @Override + public String toDelimitedString() { + return action + ActionConstants.ACTION_DELIMITER + + label + ActionConstants.ACTION_DELIMITER + + iconUri + ActionConstants.ACTION_DELIMITER; + } + + @Override + public void fromList(Context ctx, List items) { + ArrayList actionStrings = new ArrayList(); + actionStrings.addAll(items); + action = items.get(0); + label = ActionUtils.getFriendlyNameForUri(ctx, action); + iconUri = items.get(2); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(action); + dest.writeString(label); + dest.writeString(iconUri); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public ActionConfig createFromParcel(Parcel in) { + return new ActionConfig(in); + } + + public ActionConfig[] newArray(int size) { + return new ActionConfig[size]; + } + }; + + private ActionConfig(Parcel in) { + action = in.readString(); + label = in.readString(); + iconUri = in.readString(); + } + } +} diff --git a/core/java/com/android/internal/utils/ImageHelper.java b/core/java/com/android/internal/utils/ImageHelper.java new file mode 100644 index 000000000000..230ab527e82d --- /dev/null +++ b/core/java/com/android/internal/utils/ImageHelper.java @@ -0,0 +1,299 @@ +/* +* Copyright (C) 2013 SlimRoms Project +* Copyright (C) 2015 TeamEos Project +* Copyright (C) 2015-2016 The DirtyUnicorns Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.android.internal.utils; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.PorterDuffXfermode; +import android.graphics.PorterDuff.Mode; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Shader.TileMode; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.VectorDrawable; +import android.net.Uri; +import android.os.ParcelFileDescriptor; +import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.util.Xml; + +public class ImageHelper { + private static final int VECTOR_WIDTH = 512; + private static final int VECTOR_HEIGHT = 512; + + public static Drawable getColoredDrawable(Drawable d, int color) { + if (d == null) { + return null; + } + if (d instanceof VectorDrawable) { + d.setTint(color); + return d; + } + Bitmap colorBitmap = ((BitmapDrawable) d).getBitmap(); + Bitmap grayscaleBitmap = toGrayscale(colorBitmap); + Paint pp = new Paint(); + pp.setAntiAlias(true); + PorterDuffColorFilter frontFilter = + new PorterDuffColorFilter(color, Mode.MULTIPLY); + pp.setColorFilter(frontFilter); + Canvas cc = new Canvas(grayscaleBitmap); + final Rect rect = new Rect(0, 0, grayscaleBitmap.getWidth(), grayscaleBitmap.getHeight()); + cc.drawBitmap(grayscaleBitmap, rect, rect, pp); + return new BitmapDrawable(grayscaleBitmap); + } + + public static Bitmap drawableToBitmap (Drawable drawable) { + if (drawable == null) { + return null; + } else if (drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), + drawable.getIntrinsicHeight(), Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + return bitmap; + } + + public static Bitmap getColoredBitmap(Drawable d, int color) { + if (d == null) { + return null; + } + Bitmap colorBitmap = ((BitmapDrawable) d).getBitmap(); + Bitmap grayscaleBitmap = toGrayscale(colorBitmap); + Paint pp = new Paint(); + pp.setAntiAlias(true); + PorterDuffColorFilter frontFilter = + new PorterDuffColorFilter(color, Mode.MULTIPLY); + pp.setColorFilter(frontFilter); + Canvas cc = new Canvas(grayscaleBitmap); + final Rect rect = new Rect(0, 0, grayscaleBitmap.getWidth(), grayscaleBitmap.getHeight()); + cc.drawBitmap(grayscaleBitmap, rect, rect, pp); + return grayscaleBitmap; + } + + private static Bitmap toGrayscale(Bitmap bmpOriginal) { + int width, height; + height = bmpOriginal.getHeight(); + width = bmpOriginal.getWidth(); + + Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(bmpGrayscale); + Paint paint = new Paint(); + paint.setAntiAlias(true); + ColorMatrix cm = new ColorMatrix(); + final Rect rect = new Rect(0, 0, width, height); + cm.setSaturation(0); + + ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm); + paint.setColorFilter(f); + c.drawBitmap(bmpOriginal, rect, rect, paint); + return bmpGrayscale; + } + + public static Drawable resize(Context context, Drawable image, int size) { + if (image == null || context == null) { + return null; + } + if (image instanceof VectorDrawable) { + return image; + } else { + int newSize = ActionUtils.dpToPx(context, size); + Bitmap bitmap = ((BitmapDrawable) image).getBitmap(); + Bitmap scaledBitmap = Bitmap.createBitmap(newSize, newSize, Config.ARGB_8888); + + float ratioX = newSize / (float) bitmap.getWidth(); + float ratioY = newSize / (float) bitmap.getHeight(); + float middleX = newSize / 2.0f; + float middleY = newSize / 2.0f; + + final Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG); + paint.setAntiAlias(true); + + Matrix scaleMatrix = new Matrix(); + scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); + + Canvas canvas = new Canvas(scaledBitmap); + canvas.setMatrix(scaleMatrix); + canvas.drawBitmap(bitmap, middleX - bitmap.getWidth() / 2, + middleY - bitmap.getHeight() / 2, paint); + return new BitmapDrawable(context.getResources(), scaledBitmap); + } + } + + public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) { + if (bitmap == null) { + return null; + } + Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), + Config.ARGB_8888); + Canvas canvas = new Canvas(output); + + final int color = 0xff424242; + final Paint paint = new Paint(); + final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); + final RectF rectF = new RectF(rect); + final float roundPx = 24; + paint.setAntiAlias(true); + canvas.drawARGB(0, 0, 0, 0); + paint.setColor(color); + canvas.drawRoundRect(rectF, roundPx, roundPx, paint); + paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); + canvas.drawBitmap(bitmap, rect, rect, paint); + return output; + } + + public static Bitmap getCircleBitmap(Bitmap bitmap) { + if (bitmap == null) { + return null; + } + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + + Bitmap output = Bitmap.createBitmap(width, height, + Config.ARGB_8888); + Canvas canvas = new Canvas(output); + + BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); + final Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setShader(shader); + + canvas.drawCircle(width/2, height/2, width/2, paint); + + return output; + } + + public static Drawable getVector(Resources res, int resId) { + return getVector(res, resId, 0, 0, false); + } + + public static Drawable getVector(Resources res, int resId, int width, int height) { + return getVector(res, resId, width, height, false); + } + + public static Drawable getVector(Resources res, int resId, boolean toBitmapDrawable) { + return getVector(res, resId, 0, 0, toBitmapDrawable); + } + + public static Drawable getVector(Resources res, int resId, int width, int height, + boolean toBitmapDrawable) { + if (width <= 0) { + width = VECTOR_WIDTH; + } + if (height <= 0) { + width = VECTOR_HEIGHT; + } + + VectorDrawable vectorDrawable = new VectorDrawable(); + vectorDrawable.setBounds(0, 0, width, height); + try { + XmlPullParser parser = res.getXml(resId); + AttributeSet attrs = Xml.asAttributeSet(parser); + + int type; + while ((type = parser.next()) != XmlPullParser.START_TAG && + type != XmlPullParser.END_DOCUMENT) { + // Empty loop + } + + if (type != XmlPullParser.START_TAG) { +// Log.e("ImageHelper VectorLoader", "No start tag found"); + } + + vectorDrawable.inflate(res, parser, attrs); + + if (!toBitmapDrawable) { + return vectorDrawable; + } + + return new BitmapDrawable(res, drawableToBitmap(vectorDrawable)); + } catch (Exception e) { +// Log.e("ImageHelper VectorLoader", "Error loading resource ID " + String.valueOf(resId) + " Try loading as a non vector"); + return null; + } + } + + /** + * @param context callers context + * @param uri Uri to handle + * @return A bitmap from the requested uri + * @throws IOException + * + * @Credit: StackOverflow + * http://stackoverflow.com/questions/35909008/pick-image + * -from-gallery-or-google-photos-failing + */ + public static Bitmap getBitmapFromUri(Context context, Uri uri) throws IOException { + if (context == null || uri == null) { + return null; + } + ParcelFileDescriptor parcelFileDescriptor = + context.getContentResolver().openFileDescriptor(uri, "r"); + FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); + Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); + parcelFileDescriptor.close(); + return image; + } + + /** + * @param storageDir Desired location in storage as a File + * @param fileName Name of bitmap file to store + * @param bitmap the bitmap to store + * @return the Uri of the bitmap + */ + public static Uri addBitmapToStorage(File storageDir, String fileName, Bitmap bitmap) { + if (storageDir == null || fileName == null || bitmap == null) { + return null; + } + File imageFile = new File(storageDir, fileName); + try { + FileOutputStream fos = new FileOutputStream(imageFile); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); + fos.flush(); + fos.close(); + } catch (Exception e) { + return null; + } + return Uri.fromFile(imageFile); + } +} diff --git a/core/java/com/android/internal/utils/SmartPackageMonitor.java b/core/java/com/android/internal/utils/SmartPackageMonitor.java new file mode 100644 index 000000000000..14e1cb434dae --- /dev/null +++ b/core/java/com/android/internal/utils/SmartPackageMonitor.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2015-2016 The TeamEos Project + * + * Author: Randall Rushing + * + * 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. + * + * A simplified package monitor class with easy-to-use callbacks when a + * state changes. We register the receiver on background thread but post events + * to the UI thread + */ + +package com.android.internal.utils; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; + +import java.util.ArrayList; + +public class SmartPackageMonitor extends com.android.internal.content.PackageMonitor { + private static final int MSG_PACKAGE_ADDED = 1; + private static final int MSG_PACKAGE_REMOVED = 2; + private static final int MSG_PACKAGE_CHANGED = 3; + + public static enum PackageState { + PACKAGE_REMOVED, + PACKAGE_ADDED, + PACKAGE_CHANGED + } + + public interface PackageChangedListener { + public void onPackageChanged(String pkg, PackageState state); + } + + private Handler mHandler; + + private ArrayList mListeners = new ArrayList(); + + public void register(Context context, Handler foreground) { + register(context, null, null, true); + + mHandler = new Handler(foreground.getLooper()) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_PACKAGE_ADDED: + for (PackageChangedListener listener : mListeners) { + listener.onPackageChanged((String) msg.obj, PackageState.PACKAGE_ADDED); + } + break; + case MSG_PACKAGE_REMOVED: + for (PackageChangedListener listener : mListeners) { + listener.onPackageChanged((String) msg.obj, + PackageState.PACKAGE_REMOVED); + } + break; + case MSG_PACKAGE_CHANGED: + for (PackageChangedListener listener : mListeners) { + listener.onPackageChanged((String) msg.obj, + PackageState.PACKAGE_CHANGED); + } + break; + } + } + }; + } + + public void addListener(PackageChangedListener listener) { + if (listener != null) { + mListeners.add(listener); + } + } + + public void removeListener(PackageChangedListener listener) { + if (listener != null) { + mListeners.remove(listener); + } + } + + /** + * Called when a package is really added (and not replaced). + */ + public void onPackageAdded(String packageName, int uid) { + Message msg = mHandler.obtainMessage(MSG_PACKAGE_ADDED, packageName); + mHandler.sendMessage(msg); + } + + /** + * Called when a package is really removed (and not replaced). + */ + public void onPackageRemoved(String packageName, int uid) { + Message msg = mHandler.obtainMessage(MSG_PACKAGE_REMOVED, packageName); + mHandler.sendMessage(msg); + } + + /** + * Direct reflection of {@link Intent#ACTION_PACKAGE_CHANGED Intent.ACTION_PACKAGE_CHANGED} + * being received, informing you of changes to the enabled/disabled state of components in a + * package and/or of the overall package. + * + * @param packageName The name of the package that is changing. + * @param uid The user ID the package runs under. + * @param components Any components in the package that are changing. If the overall package is + * changing, this will contain an entry of the package name itself. + * @return Return true to indicate you care about this change, which will result in + * {@link #onSomePackagesChanged()} being called later. If you return false, no further + * callbacks will happen about this change. The default implementation returns true if + * this is a change to the entire package. + */ + public boolean onPackageChanged(String packageName, int uid, String[] components) { + Message msg = mHandler.obtainMessage(MSG_PACKAGE_CHANGED, packageName); + mHandler.sendMessage(msg); + return super.onPackageChanged(packageName, uid, components); + } +} diff --git a/core/java/com/android/internal/utils/SmartSystemReceiver.java b/core/java/com/android/internal/utils/SmartSystemReceiver.java new file mode 100644 index 000000000000..e8ce3f1e3d2f --- /dev/null +++ b/core/java/com/android/internal/utils/SmartSystemReceiver.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2016 The TeamEos Project + * + * Author: Randall Rushing + * + * 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. + * + * A BroadcastReceiver that filters out broadcasts from non-system + * related processes. Subclasses can allow additional broadcasting + * packages by overriding onExemptBroadcast(Context context, String packageName) + */ + +package com.android.internal.utils; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public abstract class SmartSystemReceiver extends BroadcastReceiver { + + protected abstract void onSecureReceive(Context context, Intent intent); + + protected boolean onExemptBroadcast(Context context, String packageName) { + return false; + } + + @Override + public final void onReceive(Context context, Intent intent) { + if (context == null || intent == null) { + return; + } + if (isBroadcastFromSystem(context)) { + onSecureReceive(context, intent); + } + } + + private boolean isBroadcastFromSystem(Context context) { + String packageName = context.getPackageName(); + if (packageName == null + && android.os.Process.SYSTEM_UID == context.getApplicationInfo().uid) { + packageName = "android"; + } + if (packageName == null) { + return false; + } + if (packageName.equals("com.android.systemui") + || packageName.equals("com.android.keyguard") + || packageName.equals("com.android.settings") + || packageName.equals("android") + || context.getApplicationInfo().uid == android.os.Process.SYSTEM_UID) { + return true; + } + if (onExemptBroadcast(context, packageName)) { + return true; + } + return false; + } +} diff --git a/core/java/com/android/internal/utils/UserContentObserver.java b/core/java/com/android/internal/utils/UserContentObserver.java new file mode 100644 index 000000000000..e86cdc651726 --- /dev/null +++ b/core/java/com/android/internal/utils/UserContentObserver.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2014 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 + */ +package com.android.internal.utils; + +import android.app.ActivityManagerNative; +import android.app.IUserSwitchObserver; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.IRemoteCallback; +import android.os.RemoteException; +import android.util.Log; + +/** + * Simple extension of ContentObserver that also listens for user switch events to call update + */ +public abstract class UserContentObserver extends ContentObserver { + private static final String TAG = "UserContentObserver"; + + private Runnable mUpdateRunnable; + + private IUserSwitchObserver mUserSwitchObserver = new IUserSwitchObserver.Stub() { + @Override + public void onUserSwitching(int newUserId, IRemoteCallback reply) { + } + @Override + public void onUserSwitchComplete(int newUserId) throws RemoteException { + mHandler.post(mUpdateRunnable); + } + @Override + public void onForegroundProfileSwitch(int newProfileId) { + } + @Override + public void onLockedBootComplete(int val) { + } + }; + + private Handler mHandler; + + public UserContentObserver(Handler handler) { + super(handler); + mHandler = handler; + mUpdateRunnable = new Runnable() { + @Override + public void run() { + update(); + } + }; + } + + protected void observe() { + try { + ActivityManagerNative.getDefault().registerUserSwitchObserver(mUserSwitchObserver, TAG); + } catch (RemoteException e) { + Log.w(TAG, "Unable to register user switch observer!", e); + } + } + + protected void unobserve() { + try { + mHandler.removeCallbacks(mUpdateRunnable); + ActivityManagerNative.getDefault().unregisterUserSwitchObserver(mUserSwitchObserver); + } catch (RemoteException e) { + Log.w(TAG, "Unable to unregister user switch observer!", e); + } + } + + protected abstract void update(); + + @Override + public void onChange(boolean selfChange) { + update(); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + update(); + } +} diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 591f15fd5676..f7fe87e6e9b5 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -79,4 +79,6 @@ interface ILockSettings { in byte[] recoveryKeyBlob, in List applicationKeys); void closeSession(in String sessionId); + void sanitizePassword(); + String getPassword(); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 7c339fb6d6b1..ff8f3c8b7163 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -732,6 +732,17 @@ public void saveLockPattern(List pattern, String savedPatt onAfterChangingPassword(userId); } + /** + * clears stored password. + */ + public void sanitizePassword() { + try { + getLockSettings().sanitizePassword(); + } catch (RemoteException re) { + Log.e(TAG, "Couldn't sanitize password" + re); + } + } + private void updateCryptoUserInfo(int userId) { if (userId != UserHandle.USER_SYSTEM) { return; diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index c5be8e4a3aba..a07c96ceba2e 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -25,6 +25,7 @@ import android.os.Build; import android.os.Environment; import android.os.Process; +import android.os.SystemProperties; import android.os.storage.StorageManager; import android.text.TextUtils; import android.util.ArrayMap; @@ -67,6 +68,9 @@ public class SystemConfig { private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x40; private static final int ALLOW_ALL = ~0; + // property for runtime configuration differentiation + private static final String SKU_PROPERTY = "ro.boot.product.hardware.sku"; + // Group-ids that are given to all packages as read from etc/permissions/*.xml. int[] mGlobalGids; @@ -312,6 +316,17 @@ public Map getOemPermissions(String packageName) { readPermissions(Environment.buildPath( Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag); + String skuProperty = SystemProperties.get(SKU_PROPERTY, ""); + if (!skuProperty.isEmpty()) { + String skuDir = "sku_" + skuProperty; + + readPermissions(Environment.buildPath( + Environment.getOdmDirectory(), "etc", "sysconfig", skuDir), odmPermissionFlag); + readPermissions(Environment.buildPath( + Environment.getOdmDirectory(), "etc", "permissions", skuDir), + odmPermissionFlag); + } + // Allow OEM to customize features and OEM permissions int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS; readPermissions(Environment.buildPath( @@ -319,13 +334,11 @@ public Map getOemPermissions(String packageName) { readPermissions(Environment.buildPath( Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag); - // Allow Product to customize system configs around libs, features, permissions and apps - int productPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS | - ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS; + // Allow Product to customize all system configs readPermissions(Environment.buildPath( - Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag); + Environment.getProductDirectory(), "etc", "sysconfig"), ALLOW_ALL); readPermissions(Environment.buildPath( - Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag); + Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL); } void readPermissions(File libraryDir, int permissionFlag) { @@ -344,6 +357,10 @@ void readPermissions(File libraryDir, int permissionFlag) { // Iterate over the files in the directory and scan .xml files File platformFile = null; for (File f : libraryDir.listFiles()) { + if (!f.isFile()) { + continue; + } + // We'll read platform.xml last if (f.getPath().endsWith("etc/permissions/platform.xml")) { platformFile = f; diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 13bd523e0d99..b89bbde3928c 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -37,6 +37,7 @@ cc_library_shared { cpp_std: "c++17", srcs: [ + "android_util_SeempLog.cpp", "AndroidRuntime.cpp", "com_android_internal_content_NativeLibraryHelper.cpp", "com_google_android_gles_jni_EGLImpl.cpp", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 9da3b21a613e..ea29130c2263 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -109,6 +109,7 @@ extern int register_android_media_JetPlayer(JNIEnv *env); extern int register_android_media_ToneGenerator(JNIEnv *env); namespace android { +extern int register_android_util_SeempLog(JNIEnv* env); /* * JNI-based registration functions. Note these are properly contained in @@ -1342,6 +1343,7 @@ static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env } static const RegJNIRec gRegJNI[] = { + REG_JNI(register_android_util_SeempLog), REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit), REG_JNI(register_android_os_SystemClock), diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 7f90d8ee3e4e..daf4e476ccd9 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -100,6 +100,11 @@ static jint saveLayerAlpha(jlong canvasHandle, jfloat l, jfloat t, return static_cast(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags)); } +static void restoreUnclippedLayer(jlong canvasHandle, jint saveCount, jlong paintHandle) { + Paint* paint = reinterpret_cast(paintHandle); + get_canvas(canvasHandle)->restoreUnclippedLayer(saveCount, *paint); +} + static bool restore(jlong canvasHandle) { Canvas* canvas = get_canvas(canvasHandle); if (canvas->getSaveCount() <= 1) { @@ -607,6 +612,7 @@ static const JNINativeMethod gMethods[] = { {"nSave","(JI)I", (void*) CanvasJNI::save}, {"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer}, {"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha}, + {"nRestoreUnclippedLayer","(JIJ)V", (void*) CanvasJNI::restoreUnclippedLayer}, {"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount}, {"nRestore","(J)Z", (void*) CanvasJNI::restore}, {"nRestoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount}, diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 61d5031e16ed..1ba08438e824 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -466,6 +466,77 @@ void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualM } } +static void android_hardware_Camera_setLongshot(JNIEnv *env, jobject thiz, jboolean enable) +{ + ALOGV("setLongshot"); +#ifdef QCOM_HARDWARE + JNICameraContext* context; + status_t rc; + sp camera = get_native_camera(env, thiz, &context); + if (camera == 0) return; + + if ( enable ) { + rc = camera->sendCommand(CAMERA_CMD_LONGSHOT_ON, 0, 0); + } else { + rc = camera->sendCommand(CAMERA_CMD_LONGSHOT_OFF, 0, 0); + } + + if (rc != NO_ERROR) { + jniThrowException(env, "java/lang/RuntimeException", "enabling longshot mode failed"); + } +#endif +} + +static void android_hardware_Camera_stopLongshot(JNIEnv *env, jobject thiz) +{ + ALOGV("stopLongshot"); + JNICameraContext* context; + status_t rc; + sp camera = get_native_camera(env, thiz, &context); + if (camera == 0) return; + + rc = camera->sendCommand(CAMERA_CMD_STOP_LONGSHOT, 0, 0); + + if (rc != NO_ERROR) { + jniThrowException(env, "java/lang/RuntimeException", "enabling longshot mode failed"); + } +} + +static void android_hardware_Camera_sendHistogramData(JNIEnv *env, jobject thiz) + { + ALOGV("sendHistogramData" ); +#ifdef QCOM_HARDWARE + JNICameraContext* context; + status_t rc; + sp camera = get_native_camera(env, thiz, &context); + if (camera == 0) return; + + rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_SEND_DATA, 0, 0); + + if (rc != NO_ERROR) { + jniThrowException(env, "java/lang/RuntimeException", "send histogram data failed"); + } +#endif + } + static void android_hardware_Camera_setHistogramMode(JNIEnv *env, jobject thiz, jboolean mode) + { + ALOGV("setHistogramMode: mode:%d", (int)mode); +#ifdef QCOM_HARDWARE + JNICameraContext* context; + status_t rc; + sp camera = get_native_camera(env, thiz, &context); + if (camera == 0) return; + + if(mode == true) + rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_ON, 0, 0); + else + rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_OFF, 0, 0); + + if (rc != NO_ERROR) { + jniThrowException(env, "java/lang/RuntimeException", "set histogram mode failed"); + } +#endif + } void JNICameraContext::addCallbackBuffer( JNIEnv *env, jbyteArray cbb, int msgType) { @@ -789,7 +860,25 @@ static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject t context->setCallbackMode(env, installed, manualBuffer); } -static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, jint msgType) { +static void android_hardware_Camera_setMetadataCb(JNIEnv *env, jobject thiz, jboolean mode) +{ + ALOGV("setMetadataCb: mode:%d", (int)mode); + JNICameraContext* context; + status_t rc; + sp camera = get_native_camera(env, thiz, &context); + if (camera == 0) return; + + if(mode == true) + rc = camera->sendCommand(CAMERA_CMD_METADATA_ON, 0, 0); + else + rc = camera->sendCommand(CAMERA_CMD_METADATA_OFF, 0, 0); + + if (rc != NO_ERROR) { + jniThrowException(env, "java/lang/RuntimeException", "set metadata mode failed"); + } +} + +static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, int msgType) { ALOGV("addCallbackBuffer: 0x%x", msgType); JNICameraContext* context = reinterpret_cast(env->GetLongField(thiz, fields.context)); @@ -1019,10 +1108,22 @@ static void android_hardware_Camera_enableFocusMoveCallback(JNIEnv *env, jobject } } +static void android_hardware_Camera_sendVendorCommand(JNIEnv *env, jobject thiz, + jint cmd, jint arg1, jint arg2) +{ + ALOGV("sendVendorCommand"); + sp camera = get_native_camera(env, thiz, NULL); + if (camera == 0) return; + + if (camera->sendCommand(cmd, arg1, arg2) != NO_ERROR) { + jniThrowRuntimeException(env, "sending vendor command failed"); + } +} + //------------------------------------------------- static const JNINativeMethod camMethods[] = { - { "getNumberOfCameras", + { "_getNumberOfCameras", "()I", (void *)android_hardware_Camera_getNumberOfCameras }, { "_getCameraInfo", @@ -1067,6 +1168,21 @@ static const JNINativeMethod camMethods[] = { { "native_takePicture", "(I)V", (void *)android_hardware_Camera_takePicture }, + { "native_setHistogramMode", + "(Z)V", + (void *)android_hardware_Camera_setHistogramMode }, + { "native_setMetadataCb", + "(Z)V", + (void *)android_hardware_Camera_setMetadataCb }, + { "native_sendHistogramData", + "()V", + (void *)android_hardware_Camera_sendHistogramData }, + { "native_setLongshot", + "(Z)V", + (void *)android_hardware_Camera_setLongshot }, + { "native_stopLongshot", + "()V", + (void *)android_hardware_Camera_stopLongshot }, { "native_setParameters", "(Ljava/lang/String;)V", (void *)android_hardware_Camera_setParameters }, @@ -1103,6 +1219,9 @@ static const JNINativeMethod camMethods[] = { { "enableFocusMoveCallback", "(I)V", (void *)android_hardware_Camera_enableFocusMoveCallback}, + { "_sendVendorCommand", + "(III)V", + (void *)android_hardware_Camera_sendVendorCommand }, }; struct field { diff --git a/core/jni/android_util_SeempLog.cpp b/core/jni/android_util_SeempLog.cpp new file mode 100644 index 000000000000..f788a901a8e9 --- /dev/null +++ b/core/jni/android_util_SeempLog.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2007-2014 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __BIONIC__ +#include +#endif +#include + + +#include "jni.h" +#include +#include "utils/misc.h" +#include "android_runtime/AndroidRuntime.h" + +#define LOG_BUF_SIZE 1024 +#define SEEMP_SOCK_NAME "/dev/socket/seempdw" +#define ZYGOTE_PARENT_PID 1 +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif + +static int __write_to_log_init(struct iovec *vec, size_t nr); +static int (*write_to_log)(struct iovec *vec, size_t nr) = __write_to_log_init; +static int logd_fd = -1; + +/* give up, resources too limited */ +static int __write_to_log_null(struct iovec *vec __unused, + size_t nr __unused) +{ + return -1; +} + +/* log_init_lock assumed */ +static int __write_to_log_initialize() +{ + int i, ret = 0; + if (logd_fd >= 0) { + i = logd_fd; + logd_fd = -1; + close(i); + } + + i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (i < 0) { + ret = -errno; + write_to_log = __write_to_log_null; + } else if (fcntl(i, F_SETFL, O_NONBLOCK) < 0) { + ret = -errno; + close(i); + i = -1; + write_to_log = __write_to_log_null; + } else { + struct sockaddr_un un; + memset(&un, 0, sizeof(struct sockaddr_un)); + un.sun_family = AF_UNIX; + strlcpy(un.sun_path, SEEMP_SOCK_NAME, sizeof(un.sun_path)); + if (connect(i, (struct sockaddr *)&un, sizeof(struct sockaddr_un)) < 0) { + ret = -errno; + close(i); + i = -1; + } + } + logd_fd = i; + return ret; +} + +static int __write_to_log_socket(struct iovec *vec, size_t nr) +{ + ssize_t ret; + if (logd_fd < 0) { + return -EBADF; + } + + /* + * The write below could be lost, but will never block. + * + * ENOTCONN occurs if logd dies. + * EAGAIN occurs if logd is overloaded. + */ + ret = writev(logd_fd, vec, nr); + if (ret < 0) { + ret = -errno; + if (ret == -ENOTCONN) { + ret = __write_to_log_initialize(); + if (ret < 0) { + return ret; + } + + ret = writev(logd_fd, vec, nr); + if (ret < 0) { + ret = -errno; + } + } + } + + return ret; +} + +static int __write_to_log_init(struct iovec *vec, size_t nr) +{ + if (write_to_log == __write_to_log_init) { + + if (getppid() == ZYGOTE_PARENT_PID) { + return 0; + } + + int ret; + + ret = __write_to_log_initialize(); + if (ret < 0) { + return ret; + } + + write_to_log = __write_to_log_socket; + } + return write_to_log(vec, nr); +} + +int __android_seemp_socket_write(int len, const char *msg) +{ + struct iovec vec; + vec.iov_base = (void *) msg; + vec.iov_len = len; + + return write_to_log(&vec, 1); +} + +namespace android { + +/* + * In class android.util.Log: + * public static native int println_native(int buffer, int priority, String tag, String msg) + */ +static jint android_util_SeempLog_println_native(JNIEnv* env, jobject clazz, + jint api, jstring msgObj) +{ + if (msgObj == NULL) { + jniThrowNullPointerException(env, "seemp_println needs a message"); + return -1; + } + + int apiId = (int)api; + int apiIdLen = sizeof(apiId); + int utf8MsgLen = env->GetStringUTFLength(msgObj); + int len = apiIdLen + 1 + utf8MsgLen + 1; + char *msg = (char*)malloc(len); + if ( NULL == msg ) + { + return -1; + } + char *params = msg + apiIdLen + 1; // api_id + encoding byte + params + + *((int*)msg) = apiId; // copy api id + // // skip encoding byte + env->GetStringUTFRegion(msgObj, 0, env->GetStringLength(msgObj), params); // copy message + msg[len - 1] = 0; // copy terminating zero + + int res = __android_seemp_socket_write(len, msg); // send message + + free(msg); + + return res; +} + +/* + * JNI registration. + */ +static JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "seemp_println_native", "(ILjava/lang/String;)I", + (void*) android_util_SeempLog_println_native }, +}; + +int register_android_util_SeempLog(JNIEnv* env) +{ + jclass clazz = env->FindClass("android/util/SeempLog"); + if (clazz == NULL) { + return -1; + } + + return AndroidRuntime::registerNativeMethods(env, "android/util/SeempLog", gMethods, + NELEM(gMethods)); +} + +}; // namespace android diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp index 0a90b97d55ef..d8e9c0438aa4 100644 --- a/core/jni/android_view_InputChannel.cpp +++ b/core/jni/android_view_InputChannel.cpp @@ -144,13 +144,13 @@ static jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* } jobject serverChannelObj = android_view_InputChannel_createInputChannel(env, - std::make_unique(serverChannel)); + util::make_unique(serverChannel)); if (env->ExceptionCheck()) { return NULL; } jobject clientChannelObj = android_view_InputChannel_createInputChannel(env, - std::make_unique(clientChannel)); + util::make_unique(clientChannel)); if (env->ExceptionCheck()) { return NULL; } diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h index 2ba2dc0516d0..4277545aeea4 100644 --- a/core/jni/android_view_InputChannel.h +++ b/core/jni/android_view_InputChannel.h @@ -21,6 +21,8 @@ #include +#include + namespace android { typedef void (*InputChannelObjDisposeCallback)(JNIEnv* env, jobject inputChannelObj, @@ -35,6 +37,17 @@ extern sp android_view_InputChannel_getInputChannel(JNIEnv* env, extern void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj, InputChannelObjDisposeCallback callback, void* data = NULL); +} + +namespace util { +/** + * Makes a std::unique_ptr<> with the template parameter inferred by the compiler. + * This will be present in C++14 and can be removed then. + */ +template +std::unique_ptr make_unique(Args&&... args) { + return std::unique_ptr(new T{std::forward(args)...}); +} // namespace util } // namespace android #endif // _ANDROID_OS_INPUTCHANNEL_H diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 614a8ff124ea..04b06095b022 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -308,7 +308,8 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl buffer->getHeight(), buffer->getPixelFormat(), (jint)buffer->getUsage(), - (jlong)buffer.get()); + (jlong)buffer.get(), + false /* capturedSecureLayers */); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 3aea3a767f46..fa4ebc418d2b 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -18,7 +18,6 @@ syntax = "proto2"; option java_multiple_files = true; import "frameworks/base/core/proto/android/os/backtrace.proto"; -import "frameworks/base/core/proto/android/os/batterystats.proto"; import "frameworks/base/core/proto/android/os/batterytype.proto"; import "frameworks/base/core/proto/android/os/cpufreq.proto"; import "frameworks/base/core/proto/android/os/cpuinfo.proto"; diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 237efd8f017f..0585aa8f09ee 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -467,7 +467,7 @@ message SecureSettingsProto { option (android.msg_privacy).dest = DEST_EXPLICIT; // What behavior should be invoked when the volume hush gesture is triggered - // One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE. + // One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE, VOLUME_HUSH_MUTE_NO_MEDIA. optional SettingProto hush_gesture = 1 [ (android.privacy).dest = DEST_AUTOMATIC ]; // Persisted playback time after a user confirmation of an unsafe volume level. optional SettingProto unsafe_volume_music_active_ms = 2 [ (android.privacy).dest = DEST_AUTOMATIC ]; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index d0ae9dbc55ae..7f0598994ced 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -46,6 +46,7 @@ + @@ -366,6 +367,7 @@ + @@ -605,6 +607,9 @@ + + + @@ -1269,6 +1274,11 @@ + + + @@ -2344,6 +2354,13 @@ android:description="@string/permdesc_getPackageSize" android:protectionLevel="normal" /> + + + @@ -3128,6 +3145,11 @@ + + + + + @@ -3988,6 +4015,32 @@ + + + + + + + + + + + + + + + + diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml index 371bcfef7ec9..ee29eedabb81 100644 --- a/core/res/res/anim/activity_close_enter.xml +++ b/core/res/res/anim/activity_close_enter.xml @@ -19,15 +19,16 @@ - - - \ No newline at end of file + + diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml index d87f1003def5..df4c47ac89e2 100644 --- a/core/res/res/anim/activity_close_exit.xml +++ b/core/res/res/anim/activity_close_exit.xml @@ -20,25 +20,25 @@ - - + android:interpolator="@interpolator/linear" + android:startOffset="33" + android:toAlpha="0.0" /> + diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml index cb0307026e2f..1d376a8d0f48 100644 --- a/core/res/res/anim/activity_open_enter.xml +++ b/core/res/res/anim/activity_open_enter.xml @@ -18,20 +18,25 @@ - - + + android:pivotX="50.0%" + android:pivotY="50.0%" + android:toXScale="1.0" + android:toYScale="1.0" /> diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml index d52b150391fb..74bf8321d1dc 100644 --- a/core/res/res/anim/activity_open_exit.xml +++ b/core/res/res/anim/activity_open_exit.xml @@ -18,14 +18,25 @@ - - \ No newline at end of file + android:startOffset="83" + android:toAlpha="0.4" /> + + diff --git a/core/res/res/anim/ic_bluetooth_transient_animation_0.xml b/core/res/res/anim/ic_bluetooth_transient_animation_0.xml new file mode 100644 index 000000000000..f14cfcf2beb1 --- /dev/null +++ b/core/res/res/anim/ic_bluetooth_transient_animation_0.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + diff --git a/core/res/res/anim/ic_bluetooth_transient_animation_1.xml b/core/res/res/anim/ic_bluetooth_transient_animation_1.xml new file mode 100644 index 000000000000..934bd1795765 --- /dev/null +++ b/core/res/res/anim/ic_bluetooth_transient_animation_1.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/core/res/res/anim/ic_bluetooth_transient_animation_2.xml b/core/res/res/anim/ic_bluetooth_transient_animation_2.xml new file mode 100644 index 000000000000..7dce34cc0926 --- /dev/null +++ b/core/res/res/anim/ic_bluetooth_transient_animation_2.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/core/res/res/anim/ic_hotspot_transient_animation_0.xml b/core/res/res/anim/ic_hotspot_transient_animation_0.xml new file mode 100644 index 000000000000..d5a4c521e7ff --- /dev/null +++ b/core/res/res/anim/ic_hotspot_transient_animation_0.xml @@ -0,0 +1,30 @@ + + + + + + + diff --git a/core/res/res/anim/ic_hotspot_transient_animation_1.xml b/core/res/res/anim/ic_hotspot_transient_animation_1.xml new file mode 100644 index 000000000000..36db4b956e90 --- /dev/null +++ b/core/res/res/anim/ic_hotspot_transient_animation_1.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/core/res/res/anim/ic_hotspot_transient_animation_2.xml b/core/res/res/anim/ic_hotspot_transient_animation_2.xml new file mode 100644 index 000000000000..3d6743608c87 --- /dev/null +++ b/core/res/res/anim/ic_hotspot_transient_animation_2.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/core/res/res/anim/ic_hotspot_transient_animation_3.xml b/core/res/res/anim/ic_hotspot_transient_animation_3.xml new file mode 100644 index 000000000000..1495dc98d852 --- /dev/null +++ b/core/res/res/anim/ic_hotspot_transient_animation_3.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_0.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_0.xml new file mode 100644 index 000000000000..f71d0ee30def --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_0.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_1.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_1.xml new file mode 100644 index 000000000000..9af42a10cbe9 --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_1.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_2.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_2.xml new file mode 100644 index 000000000000..0e7864a4c71b --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_2.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_3.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_3.xml new file mode 100644 index 000000000000..bbec629c1a1e --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_3.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_4.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_4.xml new file mode 100644 index 000000000000..2c921b1cec25 --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_4.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_5.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_5.xml new file mode 100644 index 000000000000..51aedc098785 --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_5.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_6.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_6.xml new file mode 100644 index 000000000000..d1da131d4d1e --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_6.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_7.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_7.xml new file mode 100644 index 000000000000..0b6eb428f0ff --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_7.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/ic_signal_wifi_transient_animation_8.xml b/core/res/res/anim/ic_signal_wifi_transient_animation_8.xml new file mode 100644 index 000000000000..3469d43d4e67 --- /dev/null +++ b/core/res/res/anim/ic_signal_wifi_transient_animation_8.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/anim/inv_app_in.xml b/core/res/res/anim/inv_app_in.xml new file mode 100644 index 000000000000..1945a61ffa39 --- /dev/null +++ b/core/res/res/anim/inv_app_in.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/core/res/res/values-mcc440/config.xml b/core/res/res/anim/inv_app_out.xml similarity index 64% rename from core/res/res/values-mcc440/config.xml rename to core/res/res/anim/inv_app_out.xml index 4ca1677fdd8d..041d36f9f1b1 100644 --- a/core/res/res/values-mcc440/config.xml +++ b/core/res/res/anim/inv_app_out.xml @@ -1,13 +1,13 @@ - - - - true - - + + + diff --git a/core/res/res/anim/launch_task_behind_source.xml b/core/res/res/anim/launch_task_behind_source.xml index a7157056f4a5..efca4a4ef2d4 100644 --- a/core/res/res/anim/launch_task_behind_source.xml +++ b/core/res/res/anim/launch_task_behind_source.xml @@ -1,48 +1,8 @@ - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/core/res/res/anim/launch_task_behind_target.xml b/core/res/res/anim/launch_task_behind_target.xml index 805918bf4b07..318ef180a8c9 100644 --- a/core/res/res/anim/launch_task_behind_target.xml +++ b/core/res/res/anim/launch_task_behind_target.xml @@ -1,34 +1,6 @@ - - - - - - - - + + + + \ No newline at end of file diff --git a/core/res/res/anim/popup_enter_material.xml b/core/res/res/anim/popup_enter_material.xml index 79de26ba144f..4ca11b866c29 100644 --- a/core/res/res/anim/popup_enter_material.xml +++ b/core/res/res/anim/popup_enter_material.xml @@ -1,22 +1,30 @@ - - - + + + diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml index b059aa9cb28c..7b21576869b0 100644 --- a/core/res/res/anim/task_close_enter.xml +++ b/core/res/res/anim/task_close_enter.xml @@ -1,69 +1,8 @@ - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml index c9ade227819b..a63ebb8aab3d 100644 --- a/core/res/res/anim/task_close_exit.xml +++ b/core/res/res/anim/task_close_exit.xml @@ -1,61 +1,8 @@ - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml index 5c618594364f..8ee1a068fa85 100644 --- a/core/res/res/anim/task_open_enter.xml +++ b/core/res/res/anim/task_open_enter.xml @@ -1,71 +1,8 @@ - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml index 9394c577da78..ec7e577d5cdc 100644 --- a/core/res/res/anim/task_open_exit.xml +++ b/core/res/res/anim/task_open_exit.xml @@ -1,61 +1,8 @@ - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml index c56efa37d3ac..5691a5b34578 100644 --- a/core/res/res/anim/wallpaper_close_enter.xml +++ b/core/res/res/anim/wallpaper_close_enter.xml @@ -1,35 +1,6 @@ - - - - - - - + + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml index 9376876e4c92..7966984e593e 100644 --- a/core/res/res/anim/wallpaper_close_exit.xml +++ b/core/res/res/anim/wallpaper_close_exit.xml @@ -1,24 +1,5 @@ - - - - + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_intra_close_enter.xml b/core/res/res/anim/wallpaper_intra_close_enter.xml index caeb8205532b..3607f58c3e37 100644 --- a/core/res/res/anim/wallpaper_intra_close_enter.xml +++ b/core/res/res/anim/wallpaper_intra_close_enter.xml @@ -1,28 +1,5 @@ - - - - - + + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_intra_close_exit.xml b/core/res/res/anim/wallpaper_intra_close_exit.xml index c61587e2f5f7..dae7bbffd7fd 100644 --- a/core/res/res/anim/wallpaper_intra_close_exit.xml +++ b/core/res/res/anim/wallpaper_intra_close_exit.xml @@ -1,30 +1,5 @@ - - - - - - - + + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_intra_open_enter.xml b/core/res/res/anim/wallpaper_intra_open_enter.xml index 939e240f12db..f790df1bab4a 100644 --- a/core/res/res/anim/wallpaper_intra_open_enter.xml +++ b/core/res/res/anim/wallpaper_intra_open_enter.xml @@ -1,30 +1,5 @@ - - - - - - + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_intra_open_exit.xml b/core/res/res/anim/wallpaper_intra_open_exit.xml index 6edd83a4cacb..f933480f6ab4 100644 --- a/core/res/res/anim/wallpaper_intra_open_exit.xml +++ b/core/res/res/anim/wallpaper_intra_open_exit.xml @@ -1,29 +1,5 @@ - - - - - - + + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml index e70f0e7d54b5..8c60a4506c7f 100644 --- a/core/res/res/anim/wallpaper_open_enter.xml +++ b/core/res/res/anim/wallpaper_open_enter.xml @@ -1,25 +1,5 @@ - - - - + + \ No newline at end of file diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml index 696912b257ac..25539a90e08c 100644 --- a/core/res/res/anim/wallpaper_open_exit.xml +++ b/core/res/res/anim/wallpaper_open_exit.xml @@ -1,40 +1,7 @@ - - - - - - - - - + + + + \ No newline at end of file diff --git a/core/res/res/drawable-hdpi/stat_notify_missed_call.png b/core/res/res/drawable-hdpi/stat_notify_missed_call.png index f205471bc5f1..37f478b1b1a2 100644 Binary files a/core/res/res/drawable-hdpi/stat_notify_missed_call.png and b/core/res/res/drawable-hdpi/stat_notify_missed_call.png differ diff --git a/core/res/res/drawable-mdpi/stat_notify_missed_call.png b/core/res/res/drawable-mdpi/stat_notify_missed_call.png index f2ff56e21ba7..cd73b12e5569 100644 Binary files a/core/res/res/drawable-mdpi/stat_notify_missed_call.png and b/core/res/res/drawable-mdpi/stat_notify_missed_call.png differ diff --git a/core/res/res/drawable-xhdpi/stat_notify_missed_call.png b/core/res/res/drawable-xhdpi/stat_notify_missed_call.png index 8719eff5ae1a..b0f2b87538df 100644 Binary files a/core/res/res/drawable-xhdpi/stat_notify_missed_call.png and b/core/res/res/drawable-xhdpi/stat_notify_missed_call.png differ diff --git a/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png b/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png index 904df3baa20d..f8c6f9b14c67 100644 Binary files a/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png and b/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png differ diff --git a/core/res/res/drawable-xxxhdpi/stat_notify_missed_call.png b/core/res/res/drawable-xxxhdpi/stat_notify_missed_call.png new file mode 100644 index 000000000000..9e604de298df Binary files /dev/null and b/core/res/res/drawable-xxxhdpi/stat_notify_missed_call.png differ diff --git a/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml b/core/res/res/drawable/adaptive_icon_drawable_wrapper.xml similarity index 51% rename from packages/SystemUI/res/anim/ic_caret_down_left_animation.xml rename to core/res/res/drawable/adaptive_icon_drawable_wrapper.xml index d465f198a679..5e592adf008f 100644 --- a/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml +++ b/core/res/res/drawable/adaptive_icon_drawable_wrapper.xml @@ -14,19 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - + + + + + + diff --git a/core/res/res/drawable/autofill_dataset_picker_background.xml b/core/res/res/drawable/autofill_dataset_picker_background.xml index b5617e177feb..c7d17b949347 100644 --- a/core/res/res/drawable/autofill_dataset_picker_background.xml +++ b/core/res/res/drawable/autofill_dataset_picker_background.xml @@ -17,6 +17,6 @@ - + diff --git a/core/res/res/drawable/emergency_icon.xml b/core/res/res/drawable/emergency_icon.xml index c142be356a2b..b2ffa2b4481c 100644 --- a/core/res/res/drawable/emergency_icon.xml +++ b/core/res/res/drawable/emergency_icon.xml @@ -18,7 +18,7 @@ Copyright (C) 2014 The Android Open Source Project android:height="24.0dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?attr/colorError"> + android:tint="?attr/colorControlNormal"> diff --git a/core/res/res/drawable/ic_bluetooth.xml b/core/res/res/drawable/ic_bluetooth.xml new file mode 100644 index 000000000000..74022a2bfac4 --- /dev/null +++ b/core/res/res/drawable/ic_bluetooth.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_bluetooth_transient_animation.xml b/core/res/res/drawable/ic_bluetooth_transient_animation.xml new file mode 100644 index 000000000000..61b0f1ad39b3 --- /dev/null +++ b/core/res/res/drawable/ic_bluetooth_transient_animation.xml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/core/res/res/drawable/ic_bluetooth_transient_animation_drawable.xml b/core/res/res/drawable/ic_bluetooth_transient_animation_drawable.xml new file mode 100644 index 000000000000..a520feabedf1 --- /dev/null +++ b/core/res/res/drawable/ic_bluetooth_transient_animation_drawable.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_faster_emergency.xml b/core/res/res/drawable/ic_faster_emergency.xml index 680dfce5d632..a37a4bc602fe 100644 --- a/core/res/res/drawable/ic_faster_emergency.xml +++ b/core/res/res/drawable/ic_faster_emergency.xml @@ -18,7 +18,7 @@ Copyright (C) 2018 The Android Open Source Project android:height="24.0dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?attr/colorError"> + android:tint="?attr/colorControlNormal"> diff --git a/core/res/res/drawable/ic_hotspot_transient_animation.xml b/core/res/res/drawable/ic_hotspot_transient_animation.xml new file mode 100644 index 000000000000..efbdfdbf6a75 --- /dev/null +++ b/core/res/res/drawable/ic_hotspot_transient_animation.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/core/res/res/drawable/ic_hotspot_transient_animation_drawable.xml b/core/res/res/drawable/ic_hotspot_transient_animation_drawable.xml new file mode 100644 index 000000000000..d81abbb8a0b8 --- /dev/null +++ b/core/res/res/drawable/ic_hotspot_transient_animation_drawable.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/ic_link.xml b/core/res/res/drawable/ic_link.xml new file mode 100644 index 000000000000..97322a4f24bd --- /dev/null +++ b/core/res/res/drawable/ic_link.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/res/res/drawable/ic_lock_lockdown.xml b/core/res/res/drawable/ic_lock_lockdown.xml index b9685d3e7cca..b6df809bbb92 100644 --- a/core/res/res/drawable/ic_lock_lockdown.xml +++ b/core/res/res/drawable/ic_lock_lockdown.xml @@ -18,7 +18,7 @@ Copyright (C) 2018 The Android Open Source Project android:height="24.0dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?attr/colorControlNormal"> + android:tint="@color/power_menu_lockdown"> + android:tint="@color/power_menu_power_off"> diff --git a/core/res/res/drawable/ic_restart.xml b/core/res/res/drawable/ic_restart.xml index 8fc285ee5829..ab2f93542fc9 100644 --- a/core/res/res/drawable/ic_restart.xml +++ b/core/res/res/drawable/ic_restart.xml @@ -18,7 +18,7 @@ android:height="24.0dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?attr/colorControlNormal"> + android:tint="@color/power_menu_restart"> diff --git a/core/res/res/drawable/ic_signal_cellular.xml b/core/res/res/drawable/ic_signal_cellular.xml new file mode 100644 index 000000000000..fdde0d107cff --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/ic_signal_cellular_0_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000000..9f6fa2f48677 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_0_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000000..9f6fa2f48677 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_1_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000000..c0fe536cf85b --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_1_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000000..816da22cf7dc --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_2_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000000..69a966ba4fc9 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_2_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000000..02c7a430cece --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_3_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000000..46ce47cdfcda --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_3_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000000..37435e6b75e2 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_4_4_bar.xml b/core/res/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000000..f93e40d9a9e8 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_4_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000000..6dc3646d89e3 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_cellular_5_5_bar.xml b/core/res/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000000..f93e40d9a9e8 --- /dev/null +++ b/core/res/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/ic_signal_wifi_badged_1_bar.xml b/core/res/res/drawable/ic_signal_wifi_badged_1_bar.xml deleted file mode 100644 index a4c5bc290d90..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_1_bar.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_badged_2_bars.xml b/core/res/res/drawable/ic_signal_wifi_badged_2_bars.xml deleted file mode 100644 index 9c27833ed4e5..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_2_bars.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_badged_3_bars.xml b/core/res/res/drawable/ic_signal_wifi_badged_3_bars.xml deleted file mode 100644 index 6d693f1cc94a..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_3_bars.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_badged_4k.xml b/core/res/res/drawable/ic_signal_wifi_badged_4k.xml deleted file mode 100644 index 0868845bee92..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_4k.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_badged_hd.xml b/core/res/res/drawable/ic_signal_wifi_badged_hd.xml deleted file mode 100644 index 657f5edf751c..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_hd.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_badged_ld.xml b/core/res/res/drawable/ic_signal_wifi_badged_ld.xml deleted file mode 100644 index e2971aa1cba0..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_ld.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_badged_sd.xml b/core/res/res/drawable/ic_signal_wifi_badged_sd.xml deleted file mode 100644 index b073be36e840..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_sd.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - diff --git a/core/res/res/drawable/ic_signal_wifi_transient_animation.xml b/core/res/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000000..0219ae52396f --- /dev/null +++ b/core/res/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + diff --git a/core/res/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/core/res/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000000..9cd4925d1f97 --- /dev/null +++ b/core/res/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/res/res/drawable/stat_notify_privacy_guard.xml b/core/res/res/drawable/stat_notify_privacy_guard.xml new file mode 100644 index 000000000000..de3aa7711b17 --- /dev/null +++ b/core/res/res/drawable/stat_notify_privacy_guard.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml index d57bd6a554e1..085e081c80db 100644 --- a/core/res/res/drawable/toast_frame.xml +++ b/core/res/res/drawable/toast_frame.xml @@ -18,7 +18,6 @@ - + - diff --git a/core/res/res/drawable/weather_clear_night.xml b/core/res/res/drawable/weather_clear_night.xml new file mode 100644 index 000000000000..0b4d42876f45 --- /dev/null +++ b/core/res/res/drawable/weather_clear_night.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/res/res/drawable/weather_cloudy.xml b/core/res/res/drawable/weather_cloudy.xml new file mode 100644 index 000000000000..778582d8b6f3 --- /dev/null +++ b/core/res/res/drawable/weather_cloudy.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_foggy.xml b/core/res/res/drawable/weather_foggy.xml new file mode 100644 index 000000000000..9239005438e0 --- /dev/null +++ b/core/res/res/drawable/weather_foggy.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/core/res/res/drawable/weather_isolated_scattered_thunderstorms.xml b/core/res/res/drawable/weather_isolated_scattered_thunderstorms.xml new file mode 100644 index 000000000000..92a700888d78 --- /dev/null +++ b/core/res/res/drawable/weather_isolated_scattered_thunderstorms.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_isolated_scattered_thunderstorms_night.xml b/core/res/res/drawable/weather_isolated_scattered_thunderstorms_night.xml new file mode 100644 index 000000000000..53d66d101eb6 --- /dev/null +++ b/core/res/res/drawable/weather_isolated_scattered_thunderstorms_night.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_mostly_clear_night.xml b/core/res/res/drawable/weather_mostly_clear_night.xml new file mode 100644 index 000000000000..ed13490aee1c --- /dev/null +++ b/core/res/res/drawable/weather_mostly_clear_night.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_mostly_cloudy.xml b/core/res/res/drawable/weather_mostly_cloudy.xml new file mode 100644 index 000000000000..6f185e5aa287 --- /dev/null +++ b/core/res/res/drawable/weather_mostly_cloudy.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_mostly_cloudy_night.xml b/core/res/res/drawable/weather_mostly_cloudy_night.xml new file mode 100644 index 000000000000..e53d9098f16c --- /dev/null +++ b/core/res/res/drawable/weather_mostly_cloudy_night.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_mostly_sunny.xml b/core/res/res/drawable/weather_mostly_sunny.xml new file mode 100644 index 000000000000..71dc3bb1ac64 --- /dev/null +++ b/core/res/res/drawable/weather_mostly_sunny.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_partly_cloudy.xml b/core/res/res/drawable/weather_partly_cloudy.xml new file mode 100644 index 000000000000..36cae1d67f79 --- /dev/null +++ b/core/res/res/drawable/weather_partly_cloudy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_partly_cloudy_night.xml b/core/res/res/drawable/weather_partly_cloudy_night.xml new file mode 100644 index 000000000000..300d33e1d0c9 --- /dev/null +++ b/core/res/res/drawable/weather_partly_cloudy_night.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_rain.xml b/core/res/res/drawable/weather_rain.xml new file mode 100644 index 000000000000..0ce87769223b --- /dev/null +++ b/core/res/res/drawable/weather_rain.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_scattered_showers.xml b/core/res/res/drawable/weather_scattered_showers.xml new file mode 100644 index 000000000000..23f1337e3dc6 --- /dev/null +++ b/core/res/res/drawable/weather_scattered_showers.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_scattered_showers_night.xml b/core/res/res/drawable/weather_scattered_showers_night.xml new file mode 100644 index 000000000000..38486f21ab51 --- /dev/null +++ b/core/res/res/drawable/weather_scattered_showers_night.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_snow.xml b/core/res/res/drawable/weather_snow.xml new file mode 100644 index 000000000000..872c9f521bd4 --- /dev/null +++ b/core/res/res/drawable/weather_snow.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_sunny.xml b/core/res/res/drawable/weather_sunny.xml new file mode 100644 index 000000000000..2819ae703182 --- /dev/null +++ b/core/res/res/drawable/weather_sunny.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_thunderstorms.xml b/core/res/res/drawable/weather_thunderstorms.xml new file mode 100644 index 000000000000..653c97335317 --- /dev/null +++ b/core/res/res/drawable/weather_thunderstorms.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/core/res/res/drawable/weather_windy.xml b/core/res/res/drawable/weather_windy.xml new file mode 100644 index 000000000000..cbc545313286 --- /dev/null +++ b/core/res/res/drawable/weather_windy.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/res/res/interpolator/transient_interpolator.xml b/core/res/res/interpolator/transient_interpolator.xml new file mode 100644 index 000000000000..653a8cfdcdc0 --- /dev/null +++ b/core/res/res/interpolator/transient_interpolator.xml @@ -0,0 +1,17 @@ + + \ No newline at end of file diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml index c3b149a1e295..4da9619a64ef 100644 --- a/core/res/res/layout/app_error_dialog.xml +++ b/core/res/res/layout/app_error_dialog.xml @@ -56,6 +56,14 @@ android:drawableStart="@drawable/ic_feedback" style="@style/aerr_list_item" /> +