getIndicatorExemptedPackages(@NonNull Context context)
pkgNames.add(exemptedPackage);
}
}
+ for (String pkgName: sLocationProviderPkgNames) {
+ if (pkgName != null) {
+ pkgNames.add(pkgName);
+ }
+ }
+ for (String pkgName: sLocationExtraPkgNames) {
+ if (pkgName != null) {
+ pkgNames.add(pkgName);
+ }
+ }
return pkgNames;
}
@@ -1180,6 +1193,10 @@ public static void updateIndicatorExemptedPackages(@NonNull Context context) {
for (int i = 0; i < EXEMPTED_ROLES.length; i++) {
INDICATOR_EXEMPTED_PACKAGES[i] = context.getString(EXEMPTED_ROLES[i]);
}
+ sLocationProviderPkgNames = context.getResources().getStringArray(
+ R.array.config_locationProviderPackageNames);
+ sLocationExtraPkgNames = context.getResources().getStringArray(
+ R.array.config_locationExtraPackageNames);
}
}
/**
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..70aa74a7f2a6
--- /dev/null
+++ b/core/java/android/pocket/PocketConstants.java
@@ -0,0 +1,19 @@
+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;
+
+}
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/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java
index c6d8c08c9141..f2becb58721f 100644
--- a/core/java/android/preference/RingtonePreference.java
+++ b/core/java/android/preference/RingtonePreference.java
@@ -33,6 +33,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 0a6a405fbce6..bd7831998741 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -113,6 +113,7 @@ public void onAudioVolumeGroupChanged(int group, int flags) {
@UnsupportedAppUsage
private final int mStreamType;
private final int mMaxStreamVolume;
+ private final boolean mVoiceCapable;
private boolean mAffectedByRingerMode;
private boolean mNotificationOrRing;
private final Receiver mReceiver = new Receiver();
@@ -206,6 +207,8 @@ public SeekBarVolumizer(
}
}
mDefaultUri = defaultUri;
+ mVoiceCapable = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_voice_capable);
}
private boolean hasAudioProductStrategies() {
@@ -254,6 +257,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);
@@ -281,13 +289,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) {
@@ -434,7 +448,7 @@ public void revertVolume() {
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
- if (fromTouch) {
+ if (fromTouch && isSeekBarEnabled()) {
postSetVolume(progress);
}
if (mCallback != null) {
@@ -631,7 +645,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/CallLog.java b/core/java/android/provider/CallLog.java
index 77c00676878c..6f1c5dbf0e1a 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -1987,7 +1987,7 @@ private static Uri addEntryAndRemoveExpiredEntries(Context context, UserManager
+ " WHERE " + PHONE_ACCOUNT_COMPONENT_NAME + " = ?"
+ " AND " + PHONE_ACCOUNT_ID + " = ?"
+ " ORDER BY " + DEFAULT_SORT_ORDER
- + " LIMIT -1 OFFSET 500)", new String[] {
+ + " LIMIT -1 OFFSET 5000)", new String[] {
values.getAsString(PHONE_ACCOUNT_COMPONENT_NAME),
values.getAsString(PHONE_ACCOUNT_ID)
});
@@ -1995,7 +1995,7 @@ private static Uri addEntryAndRemoveExpiredEntries(Context context, UserManager
// No valid phone account specified, so default to the old behavior.
resolver.delete(uri, "_id IN " +
"(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
- + " LIMIT -1 OFFSET 500)", null);
+ + " LIMIT -1 OFFSET 5000)", null);
}
return result;
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 0829d85801ac..c2dbfb8925ba 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -646,6 +646,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 6e369d343fa2..1b1d2998c011 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3344,9 +3344,26 @@ public ArrayMap getStringsForPrefix(ContentResolver cr, String p
}
}
- // Fetch all flags for the namespace at once for caching purposes
- Bundle b = cp.call(cr.getAttributionSource(),
- mProviderHolder.mUri.getAuthority(), mCallListCommand, null, args);
+ Bundle b;
+ // b/252663068: if we're in system server and the caller did not call
+ // clearCallingIdentity, the read would fail due to mismatched AttributionSources.
+ // TODO(b/256013480): remove this bypass after fixing the callers in system server.
+ if (namespace.equals(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER)
+ && Settings.isInSystemServer()
+ && Binder.getCallingUid() != Process.myUid()) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // Fetch all flags for the namespace at once for caching purposes
+ b = cp.call(cr.getAttributionSource(),
+ mProviderHolder.mUri.getAuthority(), mCallListCommand, null, args);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ } else {
+ // Fetch all flags for the namespace at once for caching purposes
+ b = cp.call(cr.getAttributionSource(),
+ mProviderHolder.mUri.getAuthority(), mCallListCommand, null, args);
+ }
if (b == null) {
// Invalid response, return an empty map
return keyValues;
@@ -3615,6 +3632,8 @@ public static final class System extends NameValueTable {
// At one time in System, then Global, but now back in Secure
MOVED_TO_SECURE.add(Secure.INSTALL_NON_MARKET_APPS);
+
+ MOVED_TO_SECURE.add(Secure.VOLUME_LINK_NOTIFICATION);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -4950,6 +4969,16 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
@Readable
public static final String RINGTONE = "ringtone";
+ /**
+ * Persistent store for the system-wide default ringtone for Slot2 URI.
+ *
+ * @see #RINGTONE
+ * @see #DEFAULT_RINGTONE2_URI
+ *
+ */
+ /** {@hide} */
+ public static final String RINGTONE2 = "ringtone2";
+
/**
* A {@link Uri} that will point to the current default ringtone at any
* given time.
@@ -4960,12 +4989,27 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
*/
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
+ *
+ */
+ /** {@hide} */
+ public static final Uri DEFAULT_RINGTONE2_URI = getUriFor(RINGTONE2);
+
/** {@hide} */
@Readable
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.
*
@@ -5128,6 +5172,12 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
@Deprecated
public static final String ANIMATOR_DURATION_SCALE = Global.ANIMATOR_DURATION_SCALE;
+ /**
+ * Whether or not to vibrate when a touchscreen gesture is detected
+ * @hide
+ */
+ public static final String TOUCHSCREEN_GESTURE_HAPTIC_FEEDBACK = "touchscreen_gesture_haptic_feedback";
+
/**
* Control whether the accelerometer will be used to change screen
* orientation. If 0, it will not be used unless explicitly requested
@@ -5265,6 +5315,12 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
@Readable
public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
+ /**
+ * Whether Proximity on Wake is Enabled or not
+ * @hide
+ */
+ public static final String PROXIMITY_ON_WAKE = "proximity_on_wake";
+
/**
* Show pointer location on screen?
* 0 = no
@@ -5453,6 +5509,11 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
@Readable
public static final String LOCK_TO_APP_ENABLED = "lock_to_app_enabled";
+ /**
+ * @hide
+ */
+ public static final String GLOBAL_ACTIONS_LIST = "global_actions_list";
+
/**
* I am the lolrus.
*
@@ -5490,6 +5551,15 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
@Readable
public static final String DESKTOP_MODE = "desktop_mode";
+ /**
+ * Whether user can swap the order of the Alert Slider.
+ * * Whether user can invert the order of the Alert Slider.
+ * 0: Default
+ * 1: Inverted
+ * @hide
+ */
+ public static final String ALERT_SLIDER_ORDER = "alert_slider_order";
+
/**
* IMPORTANT: If you add a new public settings you also have to add it to
* PUBLIC_SETTINGS below. If the new setting is hidden you have to add
@@ -5497,6 +5567,291 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
* the setting value. See an example above.
*/
+ /**
+ * Navbar style
+ * @hide
+ */
+ public static final String NAVBAR_STYLE = "navbar_style";
+
+ /**
+ * Show or hide clock
+ * 0 - hide
+ * 1 - show (default)
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK = "statusbar_clock";
+
+ /**
+ * Style of clock
+ * 0 - Left Clock (default)
+ * 1 - Center Clock
+ * 2 - Right Clock
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_STYLE = "statusbar_clock_style";
+
+ /**
+ * Whether to show seconds next to clock in status bar
+ * 0 - hide (default)
+ * 1 - show
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_SECONDS = "statusbar_clock_seconds";
+
+ /**
+ * AM/PM Style for clock options
+ * 0 - Normal AM/PM
+ * 1 - Small AM/PM
+ * 2 - No AM/PM (default)
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_AM_PM_STYLE = "statusbar_clock_am_pm_style";
+
+ /**
+ * Shows custom date before clock time
+ * 0 - No Date
+ * 1 - Small Date
+ * 2 - Normal Date
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_DISPLAY = "statusbar_clock_date_display";
+
+ /**
+ * Sets the date string style
+ * 0 - Regular style
+ * 1 - Lowercase
+ * 2 - Uppercase
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_STYLE = "statusbar_clock_date_style";
+
+ /**
+ * Stores the java DateFormat string for the date
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_FORMAT = "statusbar_clock_date_format";
+
+ /**
+ * Position of date
+ * 0 - Left of clock
+ * 1 - Right of clock
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_POSITION = "statusbar_clock_date_position";
+
+ /**
+ * Defines the screen-off animation to display
+ * @hide
+ */
+ public static final String SCREEN_OFF_ANIMATION = "screen_off_animation";
+
+ /** Volume rocker music control
+ * @hide
+ */
+ public static final String VOLUME_BUTTON_MUSIC_CONTROL = "volume_button_music_control";
+
+ /**
+ * Whether to display 4G icon instead LTE
+ * @hide
+ */
+ public static final String SHOW_FOURG_ICON = "show_fourg_icon";
+
+ /**
+ * @hide
+ */
+ public static final String USE_OLD_MOBILETYPE = "use_old_mobiletype";
+
+ /**
+ * @hide
+ */
+ public static final String SCREENSHOT_SHUTTER_SOUND = "screenshot_shutter_sound";
+
+ /**
+ * Whether 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";
+
+ /**
+ * Whether to show heads up only for dialer and sms apps
+ * @hide
+ */
+ public static final String LESS_BORING_HEADS_UP = "less_boring_heads_up";
+
+ /**
+ * Adaptive playback
+ * Automatically pause media when the volume is muted and
+ * will resume automatically when volume is restored.
+ * 0 = disabled
+ * 1 = enabled
+ * @hide
+ */
+ public static final String ADAPTIVE_PLAYBACK_ENABLED = "adaptive_playback_enabled";
+
+ /**
+ * Adaptive playback's timeout in ms
+ * @hide
+ */
+ public static final String ADAPTIVE_PLAYBACK_TIMEOUT = "adaptive_playback_timeout";
+
+ /**
+
+ /**
+ * Whether the phone vibrates on call connect
+ * @hide
+ */
+ public static final String VIBRATE_ON_CONNECT = "vibrate_on_connect";
+
+ /**
+ * Whether the phone vibrates on call waiting
+ * @hide
+ */
+ public static final String VIBRATE_ON_CALLWAITING = "vibrate_on_callwaiting";
+
+ /**
+ * Whether the phone vibrates on disconnect
+ * @hide
+ */
+ public static final String VIBRATE_ON_DISCONNECT = "vibrate_on_disconnect";
+
+ /**
+ * Double tap on lockscreen to sleep
+ * @hide
+ */
+ public static final String DOUBLE_TAP_SLEEP_LOCKSCREEN =
+ "double_tap_sleep_lockscreen";
+
+ /**
+ * Enable statusbar double tap gesture to put device to sleep
+ * @hide
+ */
+ public static final String DOUBLE_TAP_SLEEP_GESTURE = "double_tap_sleep_gesture";
+
+
+ /**
+ * 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: long tap power for torch
+ * @hide
+ */
+ public static final String TORCH_POWER_BUTTON_GESTURE = "torch_power_button_gesture";
+
+ /**
+ * Whether to hide navbar pill and keyboard space.
+ * Default 0.
+ * @hide
+ */
+ public static final String FULLSCREEN_GESTURES = "fullscreen_gestures";
+
+ /**
+ * 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 */
+ public static final String BACK_GESTURE_HAPTIC = "back_gesture_haptic";
+
+ /**
+ * Hide Statusbar on LockScreen
+ * @hide
+ */
+ public static final String HIDE_LOCKSCREEN_STATUS_BAR = "hide_lockscreen_status_bar";
+
+ /**
+ * Wheter to show network traffic indicator in statusbar
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_STATE = "network_traffic_state";
+
+ /**
+ * Network traffic inactivity threshold
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD = "network_traffic_autohide_threshold";
+
+ /**
+ * 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";
+
+ /**
+ * reTicker Status
+ * @hide
+ */
+ public static final String RETICKER_STATUS = "reticker_status";
+
+ /**
+ * reTicker Colored
+ * @hide
+ */
+ public static final String RETICKER_COLORED = "reticker_colored";
+
+ /**
+ * Only enable reTicker in landscape mode
+ * @hide
+ */
+ public static final String RETICKER_LANDSCAPE_ONLY = "reticker_landscape_only";
+
+ /**
+ * Whether to blink flashlight for incoming calls
+ * 0 = Disabled (Default)
+ * 1 = Blink flashlight only in Ringer mode
+ * 2 = Blink flashlight only when ringer is not audible
+ * 3 = Blink flahslight only when entirely silent
+ * 4 = Blink flashlight always regardless of ringer mode
+ * @hide
+ */
+ @Readable
+ public static final String FLASHLIGHT_ON_CALL = "flashlight_on_call";
+
+ /**
+ * Whether flashlight_on_call ignores DND (Zen Mode)
+ * @hide
+ */
+ @Readable
+ public static final String FLASHLIGHT_ON_CALL_IGNORE_DND = "flashlight_on_call_ignore_dnd";
+
+ /**
+ * Rate in Hz in which to blink flashlight_on_call
+ * @hide
+ */
+ @Readable
+ public static final String FLASHLIGHT_ON_CALL_RATE = "flashlight_on_call_rate";
+
+ /**
+ * Disable power menu on secure lock screens
+ *
+ * @hide
+ */
+ public static final String LOCK_POWER_MENU_DISABLED = "lockscreen_power_menu_disabled";
+
+ /**
+ * 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";
+
+ /**
+ * Bottom screen shortcuts on keyguard
+ * Two lists of strings delimeted by ;
+ * Each list of string is delimited by ,
+ * Valid strings are: home, wallet, qr, camera, flashlight and none
+ * The order in each list decides the priority for each shortcut
+ * @hide
+ */
+ @Readable
+ public static final String KEYGUARD_QUICK_TOGGLES = "keyguard_quick_toggles";
+
/**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
@@ -5509,6 +5864,65 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
public static final String[] LEGACY_RESTORE_SETTINGS = {
};
+ /**
+ * Three Finger Gesture from Oppo
+ * @hide
+ */
+ public static final String THREE_FINGER_GESTURE = "three_finger_gesture";
+
+ /**
+ * OmniJaws weather icon pack
+ * @hide
+ */
+ public static final String OMNIJAWS_WEATHER_ICON_PACK = "omnijaws_weather_icon_pack";
+
+ /**
+ * 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";
+
+ /**
+ * Enable weather in lockscreen
+ * @hide
+ */
+ public static final String OMNI_LOCKSCREEN_WEATHER_ENABLED = "lockscreen_weather_enabled";
+
+ /**
+ * 0: OmniJaws Style
+ * 1: KeyguardSlice Style
+ * @hide
+ */
+ public static final String AICP_LOCKSCREEN_WEATHER_STYLE = "lockscreen_weather_style";
+
+ /**
+ * @hide
+ */
+ public static final String LOCKSCREEN_WEATHER_SHOW_TEMP = "lockscreen_weather_show_temp";
+
+ /**
+ * @hide
+ */
+ public static final String LOCKSCREEN_WEATHER_SHOW_CITY = "lockscreen_weather_show_city";
+
/**
* These are all public system settings
*
@@ -5548,6 +5962,7 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
PUBLIC_SETTINGS.add(VOLUME_BLUETOOTH_SCO);
PUBLIC_SETTINGS.add(VOLUME_ASSISTANT);
PUBLIC_SETTINGS.add(RINGTONE);
+ PUBLIC_SETTINGS.add(RINGTONE2);
PUBLIC_SETTINGS.add(NOTIFICATION_SOUND);
PUBLIC_SETTINGS.add(ALARM_ALERT);
PUBLIC_SETTINGS.add(TEXT_AUTO_REPLACE);
@@ -5569,6 +5984,12 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
PUBLIC_SETTINGS.add(APPLY_RAMPING_RINGER);
}
+ /**
+ * Whether to show the battery info on the lockscreen while charging
+ * @hide
+ */
+ public static final String LOCKSCREEN_BATTERY_INFO = "lockscreen_battery_info";
+
/**
* These are all hidden system settings.
*
@@ -5620,6 +6041,30 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE);
PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE_VENDOR_HINT);
PRIVATE_SETTINGS.add(DESKTOP_MODE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_STYLE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_SECONDS);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_AM_PM_STYLE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_DISPLAY);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_STYLE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_FORMAT);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_POSITION);
+ PRIVATE_SETTINGS.add(VOLUME_BUTTON_MUSIC_CONTROL);
+ PRIVATE_SETTINGS.add(VIBRATE_ON_CONNECT);
+ PRIVATE_SETTINGS.add(VIBRATE_ON_CALLWAITING);
+ PRIVATE_SETTINGS.add(VIBRATE_ON_DISCONNECT);
+ PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_LOCKSCREEN);
+ PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE);
+ PRIVATE_SETTINGS.add(BACK_GESTURE_HAPTIC);
+ PRIVATE_SETTINGS.add(FLASHLIGHT_ON_CALL);
+ PRIVATE_SETTINGS.add(FLASHLIGHT_ON_CALL_IGNORE_DND);
+ PRIVATE_SETTINGS.add(FLASHLIGHT_ON_CALL_RATE);
+ PRIVATE_SETTINGS.add(POCKET_JUDGE);
+ PRIVATE_SETTINGS.add(OMNIJAWS_WEATHER_ICON_PACK);
+ PRIVATE_SETTINGS.add(OMNI_LOCKSCREEN_WEATHER_ENABLED);
+ PRIVATE_SETTINGS.add(AICP_LOCKSCREEN_WEATHER_STYLE);
+ PRIVATE_SETTINGS.add(LOCKSCREEN_WEATHER_SHOW_TEMP);
+ PRIVATE_SETTINGS.add(LOCKSCREEN_WEATHER_SHOW_CITY);
}
/**
@@ -5652,6 +6097,7 @@ public static void getCloneToManagedProfileSettings(Set outKeySet) {
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);
}
@@ -5679,6 +6125,12 @@ public static void getCloneFromParentOnValueSettings(Map outMap)
INSTANT_APP_SETTINGS.add(ACCELEROMETER_ROTATION);
}
+ /**
+ * Show app volume rows in volume panel
+ * @hide
+ */
+ public static final String SHOW_APP_VOLUME = "show_app_volume";
+
/**
* When to use Wi-Fi calling
*
@@ -10277,6 +10729,11 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
@Readable
public static final String NOTIFICATION_DISMISS_RTL = "notification_dismiss_rtl";
+ /**
+ * @hide
+ */
+ public static final String ADVANCED_REBOOT = "advanced_reboot";
+
/**
* Comma separated list of QS tiles that have been auto-added already.
* @hide
@@ -10598,6 +11055,13 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
@Readable
public static final String TAP_GESTURE = "tap_gesture";
+ /**
+ * Whether to skip biometric auth confirmation
+ * @hide
+ */
+ @Readable
+ public static final String IGNORE_AUTH_CONFIRMATION = "ignore_auth_confirmation";
+
/**
* Controls whether the people strip is enabled.
* @hide
@@ -10802,6 +11266,18 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
*/
public static final String ADAPTIVE_CONNECTIVITY_ENABLED = "adaptive_connectivity_enabled";
+ /**
+ * Boolean value whether to link ringtone and notification volume
+ * @hide
+ */
+ public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification";
+
+ /**
+ * Control whether the process CPU info meter should be shown.
+ * @hide
+ */
+ public static final String SHOW_CPU_OVERLAY = "show_cpu_overlay";
+
/**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
@@ -10966,6 +11442,64 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
public static final String EXTRA_AUTOMATIC_POWER_SAVE_MODE =
"extra_automatic_power_save_mode";
+ /**
+ * Face Unlock Method
+ * @hide
+ */
+ public static final String FACE_UNLOCK_METHOD = "face_unlock_method";
+
+ /**
+ * Whether to show Wi-Fi standard icon
+ * @hide
+ */
+ public static final String SHOW_WIFI_STANDARD_ICON = "show_wifi_standard_icon";
+
+ /**
+ * Gesture navbar length mode.
+ * Supported modes: 0 for normal length, 1 for medium and 2 for long.
+ * Default 0.
+ * @hide
+ */
+ public static final String GESTURE_NAVBAR_LENGTH_MODE = "gesture_navbar_length_mode";
+
+ /**
+ * Whether to show daily data usage in the QS footer.
+ * @hide
+ */
+ public static final String QS_SHOW_DATA_USAGE = "qs_show_data_usage";
+
+ /**
+ * Control whether FLAG_SECURE is ignored for all windows.
+ * @hide
+ */
+ @Readable
+ public static final String WINDOW_IGNORE_SECURE = "window_ignore_secure";
+
+ /**
+ * Whether to show the brightness slider in quick settings panel.
+ * @hide
+ */
+ public static final String QS_SHOW_BRIGHTNESS_SLIDER = "qs_show_brightness_slider";
+
+ /**
+ * Whether to show the brightness slider in quick settings panel.
+ * 0 = Top, 1 = Bottom
+ * @hide
+ */
+ public static final String QS_BRIGHTNESS_SLIDER_POSITION = "qs_brightness_slider_position";
+
+ /**
+ * Whether to show the auto brightness icon in quick settings panel.
+ * @hide
+ */
+ public static final String QS_SHOW_AUTO_BRIGHTNESS = "qs_show_auto_brightness";
+
+ /**
+ * Control whether GMS is enabled for this user.
+ * @hide
+ */
+ public static final String GMS_ENABLED = "gms_enabled";
+
/**
* These entries are considered common between the personal and the managed profile,
* since the managed profile doesn't get to change them.
@@ -11054,6 +11588,21 @@ public static boolean isLocationProviderEnabled(ContentResolver cr, String provi
public static void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) {
}
+
+ /**
+ * Whether UDFPS is active while the screen is off.
+ *
+ * 1 if true, 0 or unset otherwise.
+ *
+ * @hide
+ */
+ public static final String SCREEN_OFF_UDFPS_ENABLED = "screen_off_udfps_enabled";
+
+ /**
+ * Whether to scramble a pin unlock layout
+ * @hide
+ */
+ public static final String LOCKSCREEN_PIN_SCRAMBLE_LAYOUT = "lockscreen_scramble_pin_layout";
}
/**
@@ -17028,6 +17577,18 @@ public static boolean putFloat(ContentResolver cr, String name, float value) {
public static final String NR_NSA_TRACKING_SCREEN_OFF_MODE =
"nr_nsa_tracking_screen_off_mode";
+ /**
+ * The amount of time in milliseconds before wifi is turned off
+ * @hide
+ */
+ public static final String WIFI_OFF_TIMEOUT = "wifi_off_timeout";
+
+ /**
+ * The amount of time in milliseconds before bluetooth is turned off
+ * @hide
+ */
+ public static final String BLUETOOTH_OFF_TIMEOUT = "bluetooth_off_timeout";
+
/**
* Whether to show People Space.
* Values are:
@@ -18252,6 +18813,12 @@ private Panel() {
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_VOLUME =
"android.settings.panel.action.VOLUME";
+
+ /**
+ * @hide
+ */
+ public static final String ACTION_APP_VOLUME =
+ "android.settings.panel.action.APP_VOLUME";
}
/**
diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java
index 2c382efab1be..c78fb1a1f6b5 100644
--- a/core/java/android/security/keymaster/ExportResult.java
+++ b/core/java/android/security/keymaster/ExportResult.java
@@ -61,4 +61,4 @@ public void writeToParcel(Parcel out, int flags) {
out.writeInt(resultCode);
out.writeByteArray(exportData);
}
-};
+}
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 66188cd19721..f8dfef59ad33 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -71,10 +71,13 @@ public class StatusBarNotification implements Parcelable {
private Context mContext; // used for inflation & icon expansion
+ private boolean mIsContentSecure;
+
/** @hide */
public StatusBarNotification(String pkg, String opPkg, int id,
String tag, int uid, int initialPid, Notification notification, UserHandle user,
- String overrideGroupKey, long postTime) {
+ String overrideGroupKey, long postTime,
+ boolean isContentSecure) {
if (pkg == null) throw new NullPointerException();
if (notification == null) throw new NullPointerException();
@@ -90,6 +93,7 @@ public StatusBarNotification(String pkg, String opPkg, int id,
this.overrideGroupKey = overrideGroupKey;
this.key = key();
this.groupKey = groupKey();
+ mIsContentSecure = isContentSecure;
}
/**
@@ -137,6 +141,7 @@ public StatusBarNotification(Parcel in) {
}
this.key = key();
this.groupKey = groupKey();
+ mIsContentSecure = in.readBoolean();
}
/**
@@ -237,6 +242,7 @@ public void writeToParcel(Parcel out, int flags) {
} else {
out.writeInt(0);
}
+ out.writeBoolean(mIsContentSecure);
}
public int describeContents() {
@@ -276,7 +282,8 @@ public StatusBarNotification clone() {
StatusBarNotification cloneShallow(Notification notification) {
StatusBarNotification result = new StatusBarNotification(this.pkg, this.opPkg,
this.id, this.tag, this.uid, this.initialPid,
- notification, this.user, this.overrideGroupKey, this.postTime);
+ notification, this.user, this.overrideGroupKey,
+ this.postTime, mIsContentSecure);
result.setInstanceId(this.mInstanceId);
return result;
}
@@ -550,4 +557,23 @@ private String shortenTag(String logTag) {
return logTag.substring(0, MAX_LOG_TAG_LENGTH - hash.length() - 1) + "-"
+ hash;
}
+
+ /**
+ * Set whether the notification content is secure.
+ *
+ * @param isContentSecure whether the content is secure.
+ * @hide
+ */
+ public void setIsContentSecure(boolean isContentSecure) {
+ mIsContentSecure = isContentSecure;
+ }
+
+ /**
+ * Check whether the notification content is secure.
+ *
+ * @return true if content is secure, false otherwise.
+ */
+ public boolean getIsContentSecure() {
+ return mIsContentSecure;
+ }
}
diff --git a/core/java/android/text/style/AccessibilityURLSpan.java b/core/java/android/text/style/AccessibilityURLSpan.java
index bd816234a652..e280bdf8b339 100644
--- a/core/java/android/text/style/AccessibilityURLSpan.java
+++ b/core/java/android/text/style/AccessibilityURLSpan.java
@@ -26,6 +26,7 @@
* It is used to replace URLSpans in {@link AccessibilityNodeInfo#setText(CharSequence)}
* @hide
*/
+@SuppressWarnings("ParcelableCreator")
public class AccessibilityURLSpan extends URLSpan implements Parcelable {
final AccessibilityClickableSpan mAccessibilityClickableSpan;
diff --git a/core/java/android/util/AndroidException.java b/core/java/android/util/AndroidException.java
index 1345ddf189e1..d1b9d9f3c53a 100644
--- a/core/java/android/util/AndroidException.java
+++ b/core/java/android/util/AndroidException.java
@@ -40,5 +40,5 @@ protected AndroidException(String message, Throwable cause, boolean enableSuppre
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
-};
+}
diff --git a/core/java/android/util/AndroidRuntimeException.java b/core/java/android/util/AndroidRuntimeException.java
index 2b824bf9cb2a..72c34d8b75ac 100644
--- a/core/java/android/util/AndroidRuntimeException.java
+++ b/core/java/android/util/AndroidRuntimeException.java
@@ -34,5 +34,4 @@ public AndroidRuntimeException(String name, Throwable cause) {
public AndroidRuntimeException(Exception cause) {
super(cause);
}
-};
-
+}
diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java
new file mode 100644
index 000000000000..7110c1579215
--- /dev/null
+++ b/core/java/android/util/BoostFramework.java
@@ -0,0 +1,938 @@
+/*
+ * Copyright (c) 2017-2018, 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 android.app.ActivityThread;
+import android.content.Context;
+import android.graphics.BLASTBufferQueue;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import dalvik.system.PathClassLoader;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/** @hide */
+public class BoostFramework {
+
+ private static final String TAG = "BoostFramework";
+ private static final String PERFORMANCE_JAR = "/system/framework/QPerformance.jar";
+ private static final String PERFORMANCE_CLASS = "com.qualcomm.qti.Performance";
+
+ private static final String UXPERFORMANCE_JAR = "/system/framework/UxPerformance.jar";
+ private static final String UXPERFORMANCE_CLASS = "com.qualcomm.qti.UxPerformance";
+ public static final float PERF_HAL_V22 = 2.2f;
+ public static final float PERF_HAL_V23 = 2.3f;
+ public static final int VENDOR_T_API_LEVEL = 33;
+ public final int board_first_api_lvl = SystemProperties.getInt("ro.board.first_api_level", 0);
+ public final int board_api_lvl = SystemProperties.getInt("ro.board.api_level", 0);
+
+/** @hide */
+ private static boolean sIsLoaded = false;
+ private static Class> sPerfClass = null;
+ private static Method sAcquireFunc = null;
+ private static Method sPerfHintFunc = null;
+ private static Method sReleaseFunc = null;
+ private static Method sReleaseHandlerFunc = null;
+ private static Method sFeedbackFunc = null;
+ private static Method sFeedbackFuncExtn = null;
+ private static Method sPerfGetPropFunc = null;
+ private static Method sAcqAndReleaseFunc = null;
+ private static Method sperfHintAcqRelFunc = null;
+ private static Method sperfHintRenewFunc = null;
+ private static Method sPerfEventFunc = null;
+ private static Method sPerfGetPerfHalVerFunc = null;
+ private static Method sPerfSyncRequest = null;
+
+ private static Method sIOPStart = null;
+ private static Method sIOPStop = null;
+ private static Method sUXEngineEvents = null;
+ private static Method sUXEngineTrigger = null;
+
+ private static boolean sUxIsLoaded = false;
+ private static Class> sUxPerfClass = null;
+ private static Method sUxIOPStart = null;
+
+ private static boolean sIsSupported = false;
+
+/** @hide */
+ private Object mPerf = null;
+ private Object mUxPerf = null;
+
+ //perf hints
+ public static final int VENDOR_HINT_SCROLL_BOOST = 0x00001080;
+ public static final int VENDOR_HINT_FIRST_LAUNCH_BOOST = 0x00001081;
+ public static final int VENDOR_HINT_SUBSEQ_LAUNCH_BOOST = 0x00001082;
+ public static final int VENDOR_HINT_ANIM_BOOST = 0x00001083;
+ public static final int VENDOR_HINT_ACTIVITY_BOOST = 0x00001084;
+ public static final int VENDOR_HINT_TOUCH_BOOST = 0x00001085;
+ public static final int VENDOR_HINT_MTP_BOOST = 0x00001086;
+ public static final int VENDOR_HINT_DRAG_BOOST = 0x00001087;
+ public static final int VENDOR_HINT_PACKAGE_INSTALL_BOOST = 0x00001088;
+ public static final int VENDOR_HINT_ROTATION_LATENCY_BOOST = 0x00001089;
+ public static final int VENDOR_HINT_ROTATION_ANIM_BOOST = 0x00001090;
+ public static final int VENDOR_HINT_PERFORMANCE_MODE = 0x00001091;
+ public static final int VENDOR_HINT_APP_UPDATE = 0x00001092;
+ public static final int VENDOR_HINT_KILL = 0x00001093;
+ public static final int VENDOR_HINT_BOOST_RENDERTHREAD = 0x00001096;
+ //perf events
+ public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042;
+ public static final int VENDOR_HINT_TAP_EVENT = 0x00001043;
+ public static final int VENDOR_HINT_DRAG_START = 0x00001051;
+ public static final int VENDOR_HINT_DRAG_END = 0x00001052;
+ //Ime Launch Boost Hint
+ public static final int VENDOR_HINT_IME_LAUNCH_EVENT = 0x0000109F;
+
+ //feedback hints
+ public static final int VENDOR_FEEDBACK_WORKLOAD_TYPE = 0x00001601;
+ public static final int VENDOR_FEEDBACK_LAUNCH_END_POINT = 0x00001602;
+ public static final int VENDOR_FEEDBACK_PA_FW = 0x00001604;
+
+ //UXE Events and Triggers
+ public static final int UXE_TRIGGER = 1;
+ public static final int UXE_EVENT_BINDAPP = 2;
+ public static final int UXE_EVENT_DISPLAYED_ACT = 3;
+ public static final int UXE_EVENT_KILL = 4;
+ public static final int UXE_EVENT_GAME = 5;
+ public static final int UXE_EVENT_SUB_LAUNCH = 6;
+ public static final int UXE_EVENT_PKG_UNINSTALL = 7;
+ public static final int UXE_EVENT_PKG_INSTALL = 8;
+
+ //New Hints while porting IOP to Perf Hal.
+ public static final int VENDOR_HINT_BINDAPP = 0x000010A0;
+ public static final int VENDOR_HINT_WARM_LAUNCH = 0x000010A1; //SUB_LAUNCH
+ // 0x000010A2 is added in UXPerformance.java for SPEED Hints
+ public static final int VENDOR_HINT_PKG_INSTALL = 0x000010A3;
+ public static final int VENDOR_HINT_PKG_UNINSTALL = 0x000010A4;
+
+ //perf opcodes
+ public static final int MPCTLV3_GPU_IS_APP_FG = 0X42820000;
+ public static final int MPCTLV3_GPU_IS_APP_BG = 0X42824000;
+
+ public class Scroll {
+ public static final int VERTICAL = 1;
+ public static final int HORIZONTAL = 2;
+ public static final int PANEL_VIEW = 3;
+ public static final int PREFILING = 4;
+ };
+
+ public class Launch {
+ public static final int BOOST_V1 = 1;
+ public static final int BOOST_V2 = 2;
+ public static final int BOOST_V3 = 3;
+ public static final int BOOST_GAME = 4;
+ public static final int RESERVED_1 = 5;
+ public static final int RESERVED_2 = 6;
+ public static final int RESERVED_3 = 7;
+ public static final int RESERVED_4 = 8;
+ public static final int RESERVED_5 = 9;
+ public static final int ACTIVITY_LAUNCH_BOOST = 10;
+ public static final int TYPE_SERVICE_START = 100;
+ public static final int TYPE_START_PROC = 101;
+ public static final int TYPE_START_APP_FROM_BG = 102;
+ public static final int TYPE_ATTACH_APPLICATION = 103;
+ };
+
+ public class Draw {
+ public static final int EVENT_TYPE_V1 = 1;
+ };
+
+ public class WorkloadType {
+ public static final int NOT_KNOWN = 0;
+ public static final int APP = 1;
+ public static final int GAME = 2;
+ public static final int BROWSER = 3;
+ public static final int PREPROAPP = 4;
+ };
+
+/** @hide */
+ public BoostFramework() {
+ initFunctions(ActivityThread.currentActivityThread().getSystemContext());
+
+ try {
+ if (sPerfClass != null) {
+ mPerf = sPerfClass.newInstance();
+ }
+ if (sUxPerfClass != null) {
+ mUxPerf = sUxPerfClass.newInstance();
+ }
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_2 = " + e);
+ }
+ }
+
+/** @hide */
+ public BoostFramework(Context context) {
+ this(context, false);
+ }
+
+/** @hide */
+ public BoostFramework(Context context, boolean isTrusted) {
+ initFunctions(context);
+
+ try {
+ if (sPerfClass != null) {
+ Constructor cons = sPerfClass.getConstructor(Context.class);
+ if (cons != null)
+ mPerf = cons.newInstance(context);
+ }
+ if (sUxPerfClass != null) {
+ if (isTrusted) {
+ Constructor cons = sUxPerfClass.getConstructor(Context.class);
+ if (cons != null)
+ mUxPerf = cons.newInstance(context);
+ } else {
+ mUxPerf = sUxPerfClass.newInstance();
+ }
+ }
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_3 = " + e);
+ }
+ }
+
+/** @hide */
+ public BoostFramework(boolean isUntrustedDomain) {
+ initFunctions(ActivityThread.currentActivityThread().getSystemContext());
+
+ try {
+ if (sPerfClass != null) {
+ Constructor cons = sPerfClass.getConstructor(boolean.class);
+ if (cons != null)
+ mPerf = cons.newInstance(isUntrustedDomain);
+ }
+ if (sUxPerfClass != null) {
+ mUxPerf = sUxPerfClass.newInstance();
+ }
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_5 = " + e);
+ }
+ }
+
+ private void initFunctions (Context context) {
+ sIsSupported = context.getResources().getBoolean(com.android.internal.R.bool.config_supportsBoostFramework);
+
+ synchronized(BoostFramework.class) {
+ if (sIsSupported && sIsLoaded == false) {
+ try {
+ sPerfClass = Class.forName(PERFORMANCE_CLASS);
+
+ Class[] argClasses = new Class[] {int.class, int[].class};
+ sAcquireFunc = sPerfClass.getMethod("perfLockAcquire", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, int.class, int.class};
+ sPerfHintFunc = sPerfClass.getMethod("perfHint", argClasses);
+
+ argClasses = new Class[] {};
+ sReleaseFunc = sPerfClass.getMethod("perfLockRelease", argClasses);
+
+ argClasses = new Class[] {int.class};
+ sReleaseHandlerFunc = sPerfClass.getDeclaredMethod("perfLockReleaseHandler", argClasses);
+
+ argClasses = new Class[] {int.class, String.class};
+ sFeedbackFunc = sPerfClass.getMethod("perfGetFeedback", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, int.class, int[].class};
+ sFeedbackFuncExtn = sPerfClass.getMethod("perfGetFeedbackExtn", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, String.class};
+ sIOPStart = sPerfClass.getDeclaredMethod("perfIOPrefetchStart", argClasses);
+
+ argClasses = new Class[] {};
+ sIOPStop = sPerfClass.getDeclaredMethod("perfIOPrefetchStop", argClasses);
+
+ argClasses = new Class[] {String.class, String.class};
+ sPerfGetPropFunc = sPerfClass.getMethod("perfGetProp", argClasses);
+
+ argClasses = new Class[] {int.class, int.class, int.class, int.class, int[].class};
+ sAcqAndReleaseFunc = sPerfClass.getMethod("perfLockAcqAndRelease", argClasses);
+
+ argClasses = new Class[] {int.class, String.class, int.class, int[].class};
+ sPerfEventFunc = sPerfClass.getMethod("perfEvent", argClasses);
+
+ argClasses = new Class[] {int.class};
+ sPerfSyncRequest = sPerfClass.getMethod("perfSyncRequest", argClasses);
+
+ argClasses = new Class[] {int.class, int.class, String.class, int.class,
+ int.class, int.class, int[].class};
+ sperfHintAcqRelFunc = sPerfClass.getMethod("perfHintAcqRel", argClasses);
+
+ argClasses = new Class[] {int.class, int.class, String.class, int.class,
+ int.class, int.class, int[].class};
+ sperfHintRenewFunc = sPerfClass.getMethod("perfHintRenew", argClasses);
+
+ try {
+ argClasses = new Class[] {};
+ sPerfGetPerfHalVerFunc = sPerfClass.getMethod("perfGetHalVer", argClasses);
+
+ } catch (Exception e) {
+ Log.i(TAG, "BoostFramework() : Exception_1 = perfGetHalVer not supported");
+ sPerfGetPerfHalVerFunc = null;
+ }
+
+ try {
+ argClasses = new Class[] {int.class, int.class, String.class, int.class, String.class};
+ sUXEngineEvents = sPerfClass.getDeclaredMethod("perfUXEngine_events",
+ argClasses);
+
+ argClasses = new Class[] {int.class};
+ sUXEngineTrigger = sPerfClass.getDeclaredMethod("perfUXEngine_trigger",
+ argClasses);
+ } catch (Exception e) {
+ Log.i(TAG, "BoostFramework() : Exception_4 = PreferredApps not supported");
+ }
+
+ sIsLoaded = true;
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() : Exception_1 = " + e);
+ }
+ // Load UXE Class now Adding new try/catch block to avoid
+ // any interference with Qperformance
+ try {
+ sUxPerfClass = Class.forName(UXPERFORMANCE_CLASS);
+
+ Class[] argUxClasses = new Class[] {int.class, String.class, String.class};
+ sUxIOPStart = sUxPerfClass.getDeclaredMethod("perfIOPrefetchStart", argUxClasses);
+
+ sUxIsLoaded = true;
+ }
+ catch(Exception e) {
+ Log.e(TAG,"BoostFramework() Ux Perf: Exception = " + e);
+ }
+ }
+ }
+ }
+
+/** @hide */
+ public int perfLockAcquire(int duration, int... list) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sAcquireFunc != null) {
+ Object retVal = sAcquireFunc.invoke(mPerf, duration, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfLockRelease() {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sReleaseFunc != null) {
+ Object retVal = sReleaseFunc.invoke(mPerf);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfLockReleaseHandler(int handle) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sReleaseHandlerFunc != null) {
+ Object retVal = sReleaseHandlerFunc.invoke(mPerf, handle);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfHint(int hint, String userDataStr) {
+ return perfHint(hint, userDataStr, -1, -1);
+ }
+
+/** @hide */
+ public int perfHint(int hint, String userDataStr, int userData) {
+ return perfHint(hint, userDataStr, userData, -1);
+ }
+
+/** @hide */
+ public int perfHint(int hint, String userDataStr, int userData1, int userData2) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sPerfHintFunc != null) {
+ Object retVal = sPerfHintFunc.invoke(mPerf, hint, userDataStr, userData1, userData2);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public double getPerfHalVersion() {
+ double retVal = PERF_HAL_V22;
+ if (!sIsSupported){
+ return retVal;
+ }
+ try {
+ if (sPerfGetPerfHalVerFunc != null) {
+ Object ret = sPerfGetPerfHalVerFunc.invoke(mPerf);
+ retVal = (double)ret;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return retVal;
+ }
+
+/** @hide */
+ public int perfGetFeedback(int req, String pkg_name) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sFeedbackFunc != null) {
+ Object retVal = sFeedbackFunc.invoke(mPerf, req, pkg_name);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfGetFeedbackExtn(int req, String pkg_name, int numArgs, int... list) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sFeedbackFuncExtn != null) {
+ Object retVal = sFeedbackFuncExtn.invoke(mPerf, req, pkg_name, numArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfIOPrefetchStart(int pid, String pkgName, String codePath) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ Object retVal = sIOPStart.invoke(mPerf, pid, pkgName, codePath);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ try {
+ Object retVal = sUxIOPStart.invoke(mUxPerf, pid, pkgName, codePath);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Ux Perf Exception " + e);
+ }
+
+ return ret;
+ }
+
+/** @hide */
+ public int perfIOPrefetchStop() {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ Object retVal = sIOPStop.invoke(mPerf);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat) {
+ return perfUXEngine_events(opcode, pid, pkgName, lat, null);
+ }
+
+/** @hide */
+ public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat, String codePath) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sUXEngineEvents == null) {
+ return ret;
+ }
+
+ Object retVal = sUXEngineEvents.invoke(mPerf, opcode, pid, pkgName, lat,codePath);
+ ret = (int) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+
+/** @hide */
+ public String perfUXEngine_trigger(int opcode) {
+ String ret = null;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sUXEngineTrigger == null) {
+ return ret;
+ }
+ Object retVal = sUXEngineTrigger.invoke(mPerf, opcode);
+ ret = (String) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public String perfSyncRequest(int opcode) {
+ String ret = null;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sPerfSyncRequest == null) {
+ return ret;
+ }
+ Object retVal = sPerfSyncRequest.invoke(mPerf, opcode);
+ ret = (String) retVal;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public String perfGetProp(String prop_name, String def_val) {
+ String ret = "";
+ if (!sIsSupported){
+ return def_val;
+ }
+ try {
+ if (sPerfGetPropFunc != null) {
+ Object retVal = sPerfGetPropFunc.invoke(mPerf, prop_name, def_val);
+ ret = (String)retVal;
+ }else {
+ ret = def_val;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfLockAcqAndRelease(int handle, int duration, int numArgs,int reserveNumArgs, int... list) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sAcqAndReleaseFunc != null) {
+ Object retVal = sAcqAndReleaseFunc.invoke(mPerf, handle, duration, numArgs, reserveNumArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public void perfEvent(int eventId, String pkg_name) {
+ perfEvent(eventId, pkg_name, 0);
+ }
+
+/** @hide */
+ public void perfEvent(int eventId, String pkg_name, int numArgs, int... list) {
+ if (!sIsSupported){
+ return;
+ }
+ try {
+ if (sPerfEventFunc != null) {
+ sPerfEventFunc.invoke(mPerf, eventId, pkg_name, numArgs, list);
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name) {
+ return perfHintAcqRel(handle, hint, pkg_name, -1, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name, int duration) {
+ return perfHintAcqRel(handle, hint, pkg_name, duration, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name, int duration, int hintType) {
+ return perfHintAcqRel(handle, hint, pkg_name, duration, hintType, 0);
+ }
+
+/** @hide */
+ public int perfHintAcqRel(int handle, int hint, String pkg_name, int duration,
+ int hintType, int numArgs, int... list) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sperfHintAcqRelFunc != null) {
+ Object retVal = sperfHintAcqRelFunc.invoke(mPerf,handle, hint, pkg_name,
+ duration, hintType, numArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name) {
+ return perfHintRenew(handle, hint, pkg_name, -1, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name, int duration) {
+ return perfHintRenew(handle, hint, pkg_name, duration, -1, 0);
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name, int duration, int hintType) {
+ return perfHintRenew(handle, hint, pkg_name, duration, hintType, 0);
+ }
+
+/** @hide */
+ public int perfHintRenew(int handle, int hint, String pkg_name, int duration,
+ int hintType, int numArgs, int... list) {
+ int ret = -1;
+ if (!sIsSupported){
+ return ret;
+ }
+ try {
+ if (sperfHintRenewFunc != null) {
+ Object retVal = sperfHintRenewFunc.invoke(mPerf,handle, hint, pkg_name,
+ duration, hintType, numArgs, list);
+ ret = (int)retVal;
+ }
+ } catch(Exception e) {
+ Log.e(TAG,"Exception " + e);
+ }
+ return ret;
+ }
+
+ /** @hide */
+ public static class ScrollOptimizer {
+ /** @hide */
+ public static final int FLING_START = 1;
+ /** @hide */
+ public static final int FLING_END = 0;
+ private static final String SCROLL_OPT_PROP = "ro.vendor.perf.scroll_opt";
+ private static final String QXPERFORMANCE_JAR =
+ "/system/framework/QXPerformance.jar";
+ private static final String SCROLL_OPT_CLASS =
+ "com.qualcomm.qti.QXPerformance.ScrollOptimizer";
+ private static boolean sScrollOptProp = false;
+ private static boolean sScrollOptEnable = false;
+ private static boolean sQXIsLoaded = false;
+ private static Class> sQXPerfClass = null;
+ private static Method sSetFrameInterval = null;
+ private static Method sDisableOptimizer = null;
+ private static Method sSetBLASTBufferQueue = null;
+ private static Method sSetMotionType = null;
+ private static Method sSetVsyncTime = null;
+ private static Method sSetUITaskStatus = null;
+ private static Method sSetFlingFlag = null;
+ private static Method sShouldUseVsync = null;
+ private static Method sGetFrameDelay = null;
+ private static Method sGetAdjustedAnimationClock = null;
+
+ private static void initQXPerfFuncs() {
+ if (!sIsSupported || sQXIsLoaded) return;
+
+ try {
+ sScrollOptProp = SystemProperties.getBoolean(SCROLL_OPT_PROP, false);
+ if (!sScrollOptProp) {
+ sScrollOptEnable = false;
+ sQXIsLoaded = true;
+ return;
+ }
+
+ PathClassLoader qXPerfClassLoader = new PathClassLoader(
+ QXPERFORMANCE_JAR, ClassLoader.getSystemClassLoader());
+ sQXPerfClass = qXPerfClassLoader.loadClass(SCROLL_OPT_CLASS);
+ Class[] argClasses = new Class[]{long.class};
+ sSetFrameInterval = sQXPerfClass.getMethod(
+ "setFrameInterval", argClasses);
+
+ argClasses = new Class[]{boolean.class};
+ sDisableOptimizer = sQXPerfClass.getMethod("disableOptimizer", argClasses);
+
+ argClasses = new Class[]{BLASTBufferQueue.class};
+ sSetBLASTBufferQueue = sQXPerfClass.getMethod("setBLASTBufferQueue", argClasses);
+
+ argClasses = new Class[]{int.class};
+ sSetMotionType = sQXPerfClass.getMethod("setMotionType", argClasses);
+
+ argClasses = new Class[]{long.class};
+ sSetVsyncTime = sQXPerfClass.getMethod("setVsyncTime", argClasses);
+
+ argClasses = new Class[]{boolean.class};
+ sSetUITaskStatus = sQXPerfClass.getMethod("setUITaskStatus", argClasses);
+
+ argClasses = new Class[]{int.class};
+ sSetFlingFlag = sQXPerfClass.getMethod("setFlingFlag", argClasses);
+
+ sShouldUseVsync = sQXPerfClass.getMethod("shouldUseVsync");
+
+ argClasses = new Class[]{long.class};
+ sGetFrameDelay = sQXPerfClass.getMethod("getFrameDelay", argClasses);
+
+ argClasses = new Class[]{long.class};
+ sGetAdjustedAnimationClock = sQXPerfClass.getMethod(
+ "getAdjustedAnimationClock", argClasses);
+ } catch (Exception e) {
+ Log.e(TAG, "initQXPerfFuncs failed");
+ e.printStackTrace();
+ } finally {
+ // If frameworks and perf changes don't match(may not built together)
+ // or other exception, need to set sQXIsLoaded as true to avoid retry.
+ sQXIsLoaded = true;
+ }
+ }
+
+ /** @hide */
+ public static void setFrameInterval(long frameIntervalNanos) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sQXIsLoaded) {
+ if (sScrollOptEnable && sSetFrameInterval != null) {
+ try {
+ sSetFrameInterval.invoke(null, frameIntervalNanos);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return;
+ }
+ Thread initThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ synchronized(ScrollOptimizer.class) {
+ try {
+ initQXPerfFuncs();
+ if (sScrollOptProp && sSetFrameInterval != null) {
+ sSetFrameInterval.invoke(null, frameIntervalNanos);
+ sScrollOptEnable = true;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to run initThread.");
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+ initThread.start();
+ }
+
+ /** @hide */
+ public static void disableOptimizer(boolean disabled) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sScrollOptEnable && sDisableOptimizer != null) {
+ try {
+ sDisableOptimizer.invoke(null, disabled);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setBLASTBufferQueue(BLASTBufferQueue blastBufferQueue) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sScrollOptEnable && sSetBLASTBufferQueue != null) {
+ try {
+ sSetBLASTBufferQueue.invoke(null, blastBufferQueue);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setMotionType(int eventType) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sScrollOptEnable && sSetMotionType != null) {
+ try {
+ sSetMotionType.invoke(null, eventType);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setVsyncTime(long vsyncTimeNanos) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sScrollOptEnable && sSetVsyncTime != null) {
+ try {
+ sSetVsyncTime.invoke(null, vsyncTimeNanos);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setUITaskStatus(boolean running) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sScrollOptEnable && sSetUITaskStatus != null) {
+ try {
+ sSetUITaskStatus.invoke(null, running);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static void setFlingFlag(int flag) {
+ if (!sIsSupported){
+ return;
+ }
+ if (sScrollOptEnable && sSetFlingFlag != null) {
+ try {
+ sSetFlingFlag.invoke(null, flag);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** @hide */
+ public static boolean shouldUseVsync(boolean defaultVsyncFlag) {
+ boolean useVsync = defaultVsyncFlag;
+ if (!sIsSupported){
+ return useVsync;
+ }
+ if (sScrollOptEnable && sShouldUseVsync != null) {
+ try {
+ Object retVal = sShouldUseVsync.invoke(null);
+ useVsync = (boolean)retVal;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return useVsync;
+ }
+
+ /** @hide */
+ public static long getFrameDelay(long defaultDelay, long lastFrameTimeNanos) {
+ long frameDelay = defaultDelay;
+ if (!sIsSupported){
+ return frameDelay;
+ }
+ if (sScrollOptEnable && sGetFrameDelay != null) {
+ try {
+ Object retVal = sGetFrameDelay.invoke(null, lastFrameTimeNanos);
+ frameDelay = (long)retVal;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return frameDelay;
+ }
+
+ /** @hide */
+ public static long getAdjustedAnimationClock(long frameTimeNanos) {
+ long newFrameTimeNanos = frameTimeNanos;
+ if (!sIsSupported){
+ return newFrameTimeNanos;
+ }
+ if (sScrollOptEnable && sGetAdjustedAnimationClock != null) {
+ try {
+ Object retVal = sGetAdjustedAnimationClock.invoke(null,
+ frameTimeNanos);
+ newFrameTimeNanos = (long)retVal;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return newFrameTimeNanos;
+ }
+ }
+};
diff --git a/core/java/android/util/DisplayUtils.java b/core/java/android/util/DisplayUtils.java
index cbb38a4ada31..91562c5d3f5d 100644
--- a/core/java/android/util/DisplayUtils.java
+++ b/core/java/android/util/DisplayUtils.java
@@ -16,8 +16,10 @@
package android.util;
+import android.content.Context;
import android.content.res.Resources;
import android.view.Display;
+import android.view.DisplayInfo;
import com.android.internal.R;
@@ -83,4 +85,20 @@ public static float getPhysicalPixelDisplaySizeRatio(
final float heightRatio = (float) currentHeight / physicalHeight;
return Math.min(widthRatio, heightRatio);
}
+
+ /**
+ * Get the display size ratio for the current resolution vs the maximum supported
+ * resolution.
+ */
+ public static float getScaleFactor(Context context) {
+ DisplayInfo displayInfo = new DisplayInfo();
+ context.getDisplay().getDisplayInfo(displayInfo);
+ final Display.Mode maxDisplayMode =
+ getMaximumResolutionDisplayMode(displayInfo.supportedModes);
+ final float scaleFactor = getPhysicalPixelDisplaySizeRatio(
+ maxDisplayMode.getPhysicalWidth(), maxDisplayMode.getPhysicalHeight(),
+ displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight());
+
+ return scaleFactor;
+ }
}
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 4654dbfa9531..a09bc6977660 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -328,15 +328,19 @@ public int hashCode() {
}
}
- // We assume that the native methods deal with any concurrency issues.
-
/**
* Record an event log message.
* @param tag The event type tag code
* @param value A value to log
* @return The number of bytes written
*/
- public static native int writeEvent(int tag, int value);
+ public static int writeEvent(int tag, int value) {
+ if (!Build.IS_DEBUGGABLE) {
+ return 0;
+ }
+
+ return nativeWriteEvent(tag, value);
+ }
/**
* Record an event log message.
@@ -344,7 +348,13 @@ public int hashCode() {
* @param value A value to log
* @return The number of bytes written
*/
- public static native int writeEvent(int tag, long value);
+ public static int writeEvent(int tag, long value) {
+ if (!Build.IS_DEBUGGABLE) {
+ return 0;
+ }
+
+ return nativeWriteEvent(tag, value);
+ }
/**
* Record an event log message.
@@ -352,7 +362,13 @@ public int hashCode() {
* @param value A value to log
* @return The number of bytes written
*/
- public static native int writeEvent(int tag, float value);
+ public static int writeEvent(int tag, float value) {
+ if (!Build.IS_DEBUGGABLE) {
+ return 0;
+ }
+
+ return nativeWriteEvent(tag, value);
+ }
/**
* Record an event log message.
@@ -360,7 +376,13 @@ public int hashCode() {
* @param str A value to log
* @return The number of bytes written
*/
- public static native int writeEvent(int tag, String str);
+ public static int writeEvent(int tag, String str) {
+ if (!Build.IS_DEBUGGABLE) {
+ return 0;
+ }
+
+ return nativeWriteEvent(tag, str);
+ }
/**
* Record an event log message.
@@ -368,7 +390,13 @@ public int hashCode() {
* @param list A list of values to log
* @return The number of bytes written
*/
- public static native int writeEvent(int tag, Object... list);
+ public static int writeEvent(int tag, Object... list) {
+ if (!Build.IS_DEBUGGABLE) {
+ return 0;
+ }
+
+ return nativeWriteEvent(tag, list);
+ }
/**
* Read events from the log, filtered by type.
@@ -376,8 +404,14 @@ public int hashCode() {
* @param output container to add events into
* @throws IOException if something goes wrong reading events
*/
- public static native void readEvents(int[] tags, Collection output)
- throws IOException;
+ public static void readEvents(int[] tags, Collection output)
+ throws IOException {
+ if (!Build.IS_DEBUGGABLE) {
+ return;
+ }
+
+ nativeReadEvents(tags, output);
+ }
/**
* Read events from the log, filtered by type, blocking until logs are about to be overwritten.
@@ -388,7 +422,27 @@ public static native void readEvents(int[] tags, Collection output)
* @hide
*/
@SystemApi
- public static native void readEventsOnWrapping(int[] tags, long timestamp,
+ public static void readEventsOnWrapping(int[] tags, long timestamp,
+ Collection output)
+ throws IOException {
+ if (!Build.IS_DEBUGGABLE) {
+ return;
+ }
+
+ nativeReadEventsOnWrapping(tags, timestamp, output);
+ }
+
+ // We assume that the native methods deal with any concurrency issues.
+
+ private static native int nativeWriteEvent(int tag, int value);
+ private static native int nativeWriteEvent(int tag, long value);
+ private static native int nativeWriteEvent(int tag, float value);
+ private static native int nativeWriteEvent(int tag, String str);
+ private static native int nativeWriteEvent(int tag, Object... list);
+
+ private static native void nativeReadEvents(int[] tags, Collection output)
+ throws IOException;
+ private static native void nativeReadEventsOnWrapping(int[] tags, long timestamp,
Collection output)
throws IOException;
diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java
index 9fd0ab99f01b..41c171a0bbd7 100644
--- a/core/java/android/util/Range.java
+++ b/core/java/android/util/Range.java
@@ -356,4 +356,4 @@ public int hashCode() {
private final T mLower;
private final T mUpper;
-};
+}
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index 19de396c4a4a..44318bbc5468 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -696,5 +696,5 @@ public String toString()
sb.append("}");
return sb.toString();
}
-};
+}
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index d2a18dd84313..da04acedfc8d 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -33,8 +33,11 @@
import android.os.Build;
import android.os.Trace;
import android.os.incremental.V4Signature;
+import android.util.ArrayMap;
import android.util.Pair;
+import android.util.Slog;
import android.util.jar.StrictJarFile;
+import android.util.BoostFramework;
import com.android.internal.util.ArrayUtils;
@@ -53,6 +56,9 @@
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.ZipEntry;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* Facade class that takes care of the details of APK verification on
@@ -64,6 +70,12 @@ public class ApkSignatureVerifier {
private static final AtomicReference sBuffer = new AtomicReference<>();
+ private static final String TAG = "ApkSignatureVerifier";
+ // multithread verification
+ private static final int NUMBER_OF_CORES =
+ Runtime.getRuntime().availableProcessors() >= 4 ? 4 : Runtime.getRuntime().availableProcessors() ;
+ private static BoostFramework sPerfBoost = null;
+ private static boolean sIsPerfLockAcquired = false;
/**
* Verifies the provided APK and returns the certificates associated with each signer.
*/
@@ -101,6 +113,7 @@ private static ParseResult verifySignatures(ParseInput input, St
* Verifies the provided APK using all allowed signing schemas.
* @return the certificates associated with each signer and content digests.
* @param verifyFull whether to verify all contents of this APK or just collect certificates.
+ * @throws PackageParserException if there was a problem collecting certificates
* @hide
*/
public static ParseResult verifySignaturesInternal(ParseInput input,
@@ -361,32 +374,45 @@ private static ParseResult verifyV2Signature(ParseInp
*/
private static ParseResult verifyV1Signature(ParseInput input,
String apkPath, boolean verifyFull) {
- StrictJarFile jarFile = null;
-
+ int objectNumber = verifyFull ? NUMBER_OF_CORES : 1;
+ StrictJarFile[] jarFile = new StrictJarFile[objectNumber];
+ final ArrayMap strictJarFiles = new ArrayMap();
try {
final Certificate[][] lastCerts;
final Signature[] lastSigs;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
+ if (sPerfBoost == null) {
+ sPerfBoost = new BoostFramework();
+ }
+ if (sPerfBoost != null && !sIsPerfLockAcquired && verifyFull) {
+ //Use big enough number here to hold the perflock for entire PackageInstall session
+ sPerfBoost.perfHint(BoostFramework.VENDOR_HINT_PACKAGE_INSTALL_BOOST,
+ null, Integer.MAX_VALUE, -1);
+ Slog.d(TAG, "Perflock acquired for PackageInstall ");
+ sIsPerfLockAcquired = true;
+ }
// we still pass verify = true to ctor to collect certs, even though we're not checking
// the whole jar.
- jarFile = new StrictJarFile(
- apkPath,
- true, // collect certs
- verifyFull); // whether to reject APK with stripped v2 signatures (b/27887819)
+ for (int i = 0; i < objectNumber; i++) {
+ jarFile[i] = new StrictJarFile(
+ apkPath,
+ true, // collect certs
+ verifyFull); // whether to reject APK with stripped v2 signatures (b/27887819)
+ }
final List toVerify = new ArrayList<>();
// Gather certs from AndroidManifest.xml, which every APK must have, as an optimization
// to not need to verify the whole APK when verifyFUll == false.
- final ZipEntry manifestEntry = jarFile.findEntry(
+ final ZipEntry manifestEntry = jarFile[0].findEntry(
ApkLiteParseUtils.ANDROID_MANIFEST_FILENAME);
if (manifestEntry == null) {
return input.error(INSTALL_PARSE_FAILED_BAD_MANIFEST,
"Package " + apkPath + " has no manifest");
}
final ParseResult result =
- loadCertificates(input, jarFile, manifestEntry);
+ loadCertificates(input, jarFile[0], manifestEntry);
if (result.isError()) {
return input.error(result);
}
@@ -400,7 +426,7 @@ private static ParseResult verifyV1Signature(ParseInp
// fully verify all contents, except for AndroidManifest.xml and the META-INF/ files.
if (verifyFull) {
- final Iterator i = jarFile.iterator();
+ final Iterator i = jarFile[0].iterator();
while (i.hasNext()) {
final ZipEntry entry = i.next();
if (entry.isDirectory()) continue;
@@ -411,30 +437,101 @@ private static ParseResult verifyV1Signature(ParseInp
toVerify.add(entry);
}
-
+ class VerificationData {
+ public Exception exception;
+ public int exceptionFlag;
+ public boolean wait;
+ public int index;
+ public Object objWaitAll;
+ public boolean shutDown;
+ }
+ VerificationData vData = new VerificationData();
+ vData.objWaitAll = new Object();
+ final ThreadPoolExecutor verificationExecutor = new ThreadPoolExecutor(
+ NUMBER_OF_CORES,
+ NUMBER_OF_CORES,
+ 1,/*keep alive time*/
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue());
for (ZipEntry entry : toVerify) {
- final Certificate[][] entryCerts;
- final ParseResult ret =
- loadCertificates(input, jarFile, entry);
- if (ret.isError()) {
- return input.error(ret);
- }
- entryCerts = ret.getResult();
- if (ArrayUtils.isEmpty(entryCerts)) {
- return input.error(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "Package " + apkPath + " has no certificates at entry "
- + entry.getName());
+ Runnable verifyTask = new Runnable(){
+ public void run() {
+ try {
+ if (vData.exceptionFlag != 0 ) {
+ Slog.w(TAG, "VerifyV1 exit with exception " + vData.exceptionFlag);
+ return;
+ }
+ String tid = Long.toString(Thread.currentThread().getId());
+ StrictJarFile tempJarFile;
+ synchronized (strictJarFiles) {
+ tempJarFile = strictJarFiles.get(tid);
+ if (tempJarFile == null) {
+ if (vData.index >= NUMBER_OF_CORES) {
+ vData.index = 0;
+ }
+ tempJarFile = jarFile[vData.index++];
+ strictJarFiles.put(tid, tempJarFile);
+ }
+ }
+ final Certificate[][] entryCerts;
+ final ParseResult ret =
+ loadCertificates(input, tempJarFile, entry);
+ if (ret.isError()) {
+ throw new SecurityException(ret.getException());
+ }
+ entryCerts = ret.getResult();
+ if (ArrayUtils.isEmpty(entryCerts)) {
+ throw new SignatureNotFoundException("Package " + apkPath + " has no certificates at entry "
+ + entry.getName());
+ }
+
+ // make sure all entries use the same signing certs
+ final Signature[] entrySigs = convertToSignatures(entryCerts);
+ if (!Signature.areExactMatch(lastSigs, entrySigs)) {
+ throw new Exception("Package " + apkPath + " has mismatched certificates at entry "
+ + entry.getName());
+ }
+ } catch (SignatureNotFoundException | SecurityException e) {
+ synchronized (vData.objWaitAll) {
+ vData.exceptionFlag = INSTALL_PARSE_FAILED_NO_CERTIFICATES;
+ vData.exception = e;
+ }
+ } catch (GeneralSecurityException e) {
+ synchronized (vData.objWaitAll) {
+ vData.exceptionFlag = INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
+ vData.exception = e;
+ }
+ } catch (Exception e) {
+ synchronized (vData.objWaitAll) {
+ vData.exceptionFlag = INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+ vData.exception = e;
+ }
+ }
+ }};
+ synchronized (vData.objWaitAll) {
+ if (vData.exceptionFlag == 0) {
+ verificationExecutor.execute(verifyTask);
+ }
}
-
- // make sure all entries use the same signing certs
- final Signature[] entrySigs = convertToSignatures(entryCerts);
- if (!Signature.areExactMatch(lastSigs, entrySigs)) {
- return input.error(
- INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
- "Package " + apkPath + " has mismatched certificates at entry "
- + entry.getName());
+ }
+ vData.wait = true;
+ verificationExecutor.shutdown();
+ while (vData.wait) {
+ try {
+ if (vData.exceptionFlag != 0 && !vData.shutDown) {
+ Slog.w(TAG, "verifyV1 Exception " + vData.exceptionFlag);
+ verificationExecutor.shutdownNow();
+ vData.shutDown = true;
+ }
+ vData.wait = !verificationExecutor.awaitTermination(50,
+ TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.w(TAG,"VerifyV1 interrupted while awaiting all threads done...");
}
}
+ if (vData.exceptionFlag != 0)
+ return input.error(vData.exceptionFlag,
+ "Failed to collect certificates from " + apkPath, vData.exception);
}
return input.success(new SigningDetailsWithDigests(
new SigningDetails(lastSigs, SignatureSchemeVersion.JAR), null));
@@ -445,8 +542,16 @@ private static ParseResult verifyV1Signature(ParseInp
return input.error(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"Failed to collect certificates from " + apkPath, e);
} finally {
+ if (sIsPerfLockAcquired && sPerfBoost != null) {
+ sPerfBoost.perfLockRelease();
+ sIsPerfLockAcquired = false;
+ Slog.d(TAG, "Perflock released for PackageInstall ");
+ }
+ strictJarFiles.clear();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- closeQuietly(jarFile);
+ for (int i = 0; i < objectNumber ; i++) {
+ closeQuietly(jarFile[i]);
+ }
}
}
@@ -512,9 +617,6 @@ private static void closeQuietly(StrictJarFile jarFile) {
* {@code targetSdk}.
*/
public static int getMinimumSignatureSchemeVersionForTargetSdk(int targetSdk) {
- if (targetSdk >= Build.VERSION_CODES.R) {
- return SignatureSchemeVersion.SIGNING_BLOCK_V2;
- }
return SignatureSchemeVersion.JAR;
}
diff --git a/core/java/android/view/CutoutSpecification.java b/core/java/android/view/CutoutSpecification.java
index f8aa934af595..3fc3b6a3ccb3 100644
--- a/core/java/android/view/CutoutSpecification.java
+++ b/core/java/android/view/CutoutSpecification.java
@@ -394,7 +394,6 @@ private void parseSvgPathSpec(Region region, String spec) {
Log.e(TAG, "According to SVG definition, it shouldn't happen");
return;
}
- spec.trim();
translateMatrix();
final Path newPath = PathParser.createPathFromPathData(spec);
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index df78827534a6..cd2ea4311264 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -804,67 +804,75 @@ public final View createView(@NonNull Context viewContext, @NonNull String name,
throws ClassNotFoundException, InflateException {
Objects.requireNonNull(viewContext);
Objects.requireNonNull(name);
- Constructor extends View> constructor = sConstructorMap.get(name);
- if (constructor != null && !verifyClassLoader(constructor)) {
- constructor = null;
- sConstructorMap.remove(name);
- }
+ String prefixedName = prefix != null ? (prefix + name) : name;
Class extends View> clazz = null;
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, name);
- if (constructor == null) {
- // Class not found in the cache, see if it's real, and try to add it
- clazz = Class.forName(prefix != null ? (prefix + name) : name, false,
- mContext.getClassLoader()).asSubclass(View.class);
-
- if (mFilter != null && clazz != null) {
- boolean allowed = mFilter.onLoadClass(clazz);
- if (!allowed) {
- failNotAllowed(name, prefix, viewContext, attrs);
- }
+ // Opportunistically create view directly instead of using reflection
+ View view = tryCreateViewDirect(prefixedName, viewContext, attrs);
+ if (view == null) {
+ Constructor extends View> constructor = sConstructorMap.get(name);
+ if (constructor != null && !verifyClassLoader(constructor)) {
+ constructor = null;
+ sConstructorMap.remove(name);
}
- constructor = clazz.getConstructor(mConstructorSignature);
- constructor.setAccessible(true);
- sConstructorMap.put(name, constructor);
- } else {
- // If we have a filter, apply it to cached constructor
- if (mFilter != null) {
- // Have we seen this name before?
- Boolean allowedState = mFilterMap.get(name);
- if (allowedState == null) {
- // New class -- remember whether it is allowed
- clazz = Class.forName(prefix != null ? (prefix + name) : name, false,
- mContext.getClassLoader()).asSubclass(View.class);
-
- boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
- mFilterMap.put(name, allowed);
+
+ if (constructor == null) {
+ // Class not found in the cache, see if it's real, and try to add it
+ clazz = Class.forName(prefixedName, false,
+ mContext.getClassLoader()).asSubclass(View.class);
+
+ if (mFilter != null && clazz != null) {
+ boolean allowed = mFilter.onLoadClass(clazz);
if (!allowed) {
failNotAllowed(name, prefix, viewContext, attrs);
}
- } else if (allowedState.equals(Boolean.FALSE)) {
- failNotAllowed(name, prefix, viewContext, attrs);
+ }
+ constructor = clazz.getConstructor(mConstructorSignature);
+ constructor.setAccessible(true);
+ sConstructorMap.put(name, constructor);
+ } else {
+ // If we have a filter, apply it to cached constructor
+ if (mFilter != null) {
+ // Have we seen this name before?
+ Boolean allowedState = mFilterMap.get(name);
+ if (allowedState == null) {
+ // New class -- remember whether it is allowed
+ clazz = Class.forName(prefixedName, false,
+ mContext.getClassLoader()).asSubclass(View.class);
+
+ boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
+ mFilterMap.put(name, allowed);
+ if (!allowed) {
+ failNotAllowed(name, prefix, viewContext, attrs);
+ }
+ } else if (allowedState.equals(Boolean.FALSE)) {
+ failNotAllowed(name, prefix, viewContext, attrs);
+ }
}
}
- }
- Object lastContext = mConstructorArgs[0];
- mConstructorArgs[0] = viewContext;
- Object[] args = mConstructorArgs;
- args[1] = attrs;
+ Object lastContext = mConstructorArgs[0];
+ mConstructorArgs[0] = viewContext;
+ Object[] args = mConstructorArgs;
+ args[1] = attrs;
- try {
- final View view = constructor.newInstance(args);
- if (view instanceof ViewStub) {
- // Use the same context when inflating ViewStub later.
- final ViewStub viewStub = (ViewStub) view;
- viewStub.setLayoutInflater(cloneInContext((Context) args[0]));
+ try {
+ view = constructor.newInstance(args);
+ } finally {
+ mConstructorArgs[0] = lastContext;
}
- return view;
- } finally {
- mConstructorArgs[0] = lastContext;
}
+
+ if (view instanceof ViewStub) {
+ // Use the same context when inflating ViewStub later.
+ final ViewStub viewStub = (ViewStub) view;
+ viewStub.setLayoutInflater(cloneInContext((Context) viewContext));
+ }
+
+ return view;
} catch (NoSuchMethodException e) {
final InflateException ie = new InflateException(
getParserStateDescription(viewContext, attrs)
@@ -1363,4 +1371,121 @@ protected void dispatchDraw(Canvas canvas) {
}
}
}
+
+ // Some of the views included here are deprecated, but apps still use them.
+ @SuppressWarnings("deprecation")
+ private static View tryCreateViewDirect(String name, Context context, AttributeSet attributeSet) {
+ // This contains all the framework views used in a set of 113 real-world apps, sorted by
+ // number of occurrences. While views with only 1 occurrence are unlikely to be worth
+ // optimizing, it doesn't hurt to include them because switch-case is compiled into a table
+ // lookup after calling String#hashCode().
+ switch (name) {
+ case "android.widget.LinearLayout": // 13486 occurrences
+ return new android.widget.LinearLayout(context, attributeSet);
+ case "android.widget.View": // 6930 occurrences
+ case "android.webkit.View": // 63 occurrences
+ case "android.view.View": // 63 occurrences
+ case "android.app.View": // 62 occurrences
+ return new android.view.View(context, attributeSet);
+ case "android.widget.FrameLayout": // 6447 occurrences
+ return new android.widget.FrameLayout(context, attributeSet);
+ case "android.widget.ViewStub": // 5613 occurrences
+ case "android.view.ViewStub": // 228 occurrences
+ case "android.app.ViewStub": // 227 occurrences
+ case "android.webkit.ViewStub": // 226 occurrences
+ return new android.view.ViewStub(context, attributeSet);
+ case "android.widget.TextView": // 4722 occurrences
+ return new android.widget.TextView(context, attributeSet);
+ case "android.widget.ImageView": // 3044 occurrences
+ return new android.widget.ImageView(context, attributeSet);
+ case "android.widget.RelativeLayout": // 2665 occurrences
+ return new android.widget.RelativeLayout(context, attributeSet);
+ case "android.widget.Space": // 1694 occurrences
+ return new android.widget.Space(context, attributeSet);
+ case "android.widget.ProgressBar": // 770 occurrences
+ return new android.widget.ProgressBar(context, attributeSet);
+ case "android.widget.Button": // 382 occurrences
+ return new android.widget.Button(context, attributeSet);
+ case "android.widget.ImageButton": // 265 occurrences
+ return new android.widget.ImageButton(context, attributeSet);
+ case "android.widget.Switch": // 145 occurrences
+ return new android.widget.Switch(context, attributeSet);
+ case "android.widget.DateTimeView": // 117 occurrences
+ return new android.widget.DateTimeView(context, attributeSet);
+ case "android.widget.Toolbar": // 86 occurrences
+ return new android.widget.Toolbar(context, attributeSet);
+ case "android.widget.HorizontalScrollView": // 68 occurrences
+ return new android.widget.HorizontalScrollView(context, attributeSet);
+ case "android.widget.ScrollView": // 67 occurrences
+ return new android.widget.ScrollView(context, attributeSet);
+ case "android.widget.NotificationHeaderView": // 65 occurrences
+ case "android.webkit.NotificationHeaderView": // 65 occurrences
+ case "android.view.NotificationHeaderView": // 65 occurrences
+ case "android.app.NotificationHeaderView": // 65 occurrences
+ return new android.view.NotificationHeaderView(context, attributeSet);
+ case "android.widget.ListView": // 58 occurrences
+ return new android.widget.ListView(context, attributeSet);
+ case "android.widget.QuickContactBadge": // 50 occurrences
+ return new android.widget.QuickContactBadge(context, attributeSet);
+ case "android.widget.SeekBar": // 40 occurrences
+ return new android.widget.SeekBar(context, attributeSet);
+ case "android.widget.CheckBox": // 38 occurrences
+ return new android.widget.CheckBox(context, attributeSet);
+ case "android.widget.GridLayout": // 16 occurrences
+ return new android.widget.GridLayout(context, attributeSet);
+ case "android.widget.TableRow": // 15 occurrences
+ return new android.widget.TableRow(context, attributeSet);
+ case "android.widget.RadioGroup": // 15 occurrences
+ return new android.widget.RadioGroup(context, attributeSet);
+ case "android.widget.Chronometer": // 15 occurrences
+ return new android.widget.Chronometer(context, attributeSet);
+ case "android.widget.ViewFlipper": // 13 occurrences
+ return new android.widget.ViewFlipper(context, attributeSet);
+ case "android.widget.Spinner": // 9 occurrences
+ return new android.widget.Spinner(context, attributeSet);
+ case "android.widget.ViewSwitcher": // 8 occurrences
+ return new android.widget.ViewSwitcher(context, attributeSet);
+ case "android.widget.TextSwitcher": // 8 occurrences
+ return new android.widget.TextSwitcher(context, attributeSet);
+ case "android.widget.SurfaceView": // 8 occurrences
+ case "android.webkit.SurfaceView": // 1 occurrence
+ case "android.view.SurfaceView": // 1 occurrence
+ case "android.app.SurfaceView": // 1 occurrence
+ return new android.view.SurfaceView(context, attributeSet);
+ case "android.widget.CheckedTextView": // 8 occurrences
+ return new android.widget.CheckedTextView(context, attributeSet);
+ case "android.preference.PreferenceFrameLayout": // 8 occurrences
+ return new android.preference.PreferenceFrameLayout(context, attributeSet);
+ case "android.widget.TwoLineListItem": // 7 occurrences
+ return new android.widget.TwoLineListItem(context, attributeSet);
+ case "android.widget.TableLayout": // 5 occurrences
+ return new android.widget.TableLayout(context, attributeSet);
+ case "android.widget.EditText": // 5 occurrences
+ return new android.widget.EditText(context, attributeSet);
+ case "android.widget.TabWidget": // 3 occurrences
+ return new android.widget.TabWidget(context, attributeSet);
+ case "android.widget.TabHost": // 3 occurrences
+ return new android.widget.TabHost(context, attributeSet);
+ case "android.widget.ZoomButton": // 2 occurrences
+ return new android.widget.ZoomButton(context, attributeSet);
+ case "android.widget.TextureView": // 2 occurrences
+ case "android.webkit.TextureView": // 2 occurrences
+ case "android.app.TextureView": // 2 occurrences
+ case "android.view.TextureView": // 2 occurrences
+ return new android.view.TextureView(context, attributeSet);
+ case "android.widget.ExpandableListView": // 2 occurrences
+ return new android.widget.ExpandableListView(context, attributeSet);
+ case "android.widget.ViewAnimator": // 1 occurrence
+ return new android.widget.ViewAnimator(context, attributeSet);
+ case "android.widget.TextClock": // 1 occurrence
+ return new android.widget.TextClock(context, attributeSet);
+ case "android.widget.AutoCompleteTextView": // 1 occurrence
+ return new android.widget.AutoCompleteTextView(context, attributeSet);
+ case "android.widget.WebView": // 1 occurrence
+ case "android.webkit.WebView": // 1 occurrence
+ return new android.webkit.WebView(context, attributeSet);
+ }
+
+ return null;
+ }
}
diff --git a/core/java/android/view/RemoteAnimationDefinition.java b/core/java/android/view/RemoteAnimationDefinition.java
index ea9799584e20..ff282ba0da39 100644
--- a/core/java/android/view/RemoteAnimationDefinition.java
+++ b/core/java/android/view/RemoteAnimationDefinition.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import android.annotation.Nullable;
+import android.annotation.NonNull;
import android.app.WindowConfiguration.ActivityType;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.IBinder;
@@ -157,7 +158,7 @@ public void writeToParcel(Parcel dest, int flags) {
}
}
- public static final @android.annotation.NonNull Creator CREATOR =
+ public static final @NonNull Creator CREATOR =
new Creator() {
public RemoteAnimationDefinition createFromParcel(Parcel in) {
return new RemoteAnimationDefinition(in);
@@ -199,18 +200,17 @@ public int describeContents() {
return 0;
}
- private static final @android.annotation.NonNull Creator CREATOR
- = new Creator() {
-
- @Override
- public RemoteAnimationAdapterEntry createFromParcel(Parcel in) {
- return new RemoteAnimationAdapterEntry(in);
- }
-
- @Override
- public RemoteAnimationAdapterEntry[] newArray(int size) {
- return new RemoteAnimationAdapterEntry[size];
- }
- };
+ public static final @NonNull Parcelable.Creator CREATOR =
+ new Parcelable.Creator() {
+ @Override
+ public RemoteAnimationAdapterEntry createFromParcel(Parcel in) {
+ return new RemoteAnimationAdapterEntry(in);
+ }
+
+ @Override
+ public RemoteAnimationAdapterEntry[] newArray(int size) {
+ return new RemoteAnimationAdapterEntry[size];
+ }
+ };
}
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 638b8f9f9b40..6d6692c64a5d 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -74,7 +74,7 @@ public class ViewConfiguration {
* a long press
* @hide
*/
- public static final int DEFAULT_LONG_PRESS_TIMEOUT = 400;
+ public static final int DEFAULT_LONG_PRESS_TIMEOUT = 300;
/**
* Defines the default duration in milliseconds between the first tap's up event and the second
@@ -92,7 +92,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
@@ -124,7 +124,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
@@ -158,12 +158,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.
@@ -222,7 +222,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.
@@ -243,7 +243,7 @@ public class ViewConfiguration {
* The coefficient of friction applied to flings/scrolls.
*/
@UnsupportedAppUsage
- 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 e4caa385bc9b..2006d8265f96 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6649,6 +6649,11 @@ private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
mHandwritingInitiator.onTouchEvent(event);
+ if (event.getPointerCount() == 3 && isSwipeToScreenshotGestureActive()) {
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ Log.d("teste", "canceling motionEvent because of threeGesture detecting");
+ }
+
mAttachInfo.mUnbufferedDispatchRequested = false;
mAttachInfo.mHandlingPointerEvent = true;
boolean handled = mView.dispatchPointerEvent(event);
@@ -11114,4 +11119,13 @@ void mergeSync(int syncId, SurfaceSyncer otherSyncer) {
}
mSurfaceSyncer.merge(mSyncId, syncId, otherSyncer);
}
+
+ private boolean isSwipeToScreenshotGestureActive() {
+ try {
+ return ActivityManager.getService().isSwipeToScreenshotGestureActive();
+ } catch (RemoteException e) {
+ Log.e("teste", "isSwipeToScreenshotGestureActive exception", e);
+ return false;
+ }
+ }
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 02027e4a3969..22e605bdc3ad 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -20,6 +20,7 @@
import static android.Manifest.permission.HIDE_OVERLAY_WINDOWS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import android.annotation.ColorInt;
@@ -50,6 +51,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.provider.Settings;
import android.transition.Scene;
import android.transition.Transition;
import android.transition.TransitionManager;
@@ -1274,6 +1276,10 @@ public void clearFlags(int flags) {
* @see #clearFlags
*/
public void setFlags(int flags, int mask) {
+ if ((mask & FLAG_SECURE) != 0 && Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.WINDOW_IGNORE_SECURE, 0) == 1) {
+ mask &= ~FLAG_SECURE;
+ }
final WindowManager.LayoutParams attrs = getAttributes();
attrs.flags = (attrs.flags&~mask) | (flags&mask);
mForcedWindowFlags |= mask;
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index d37756551db3..ae9a1220a246 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -32,6 +32,7 @@
import android.os.SystemProperties;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
+import android.util.BoostFramework.ScrollOptimizer;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
@@ -362,10 +363,12 @@ public void addView(View view, ViewGroup.LayoutParams params,
// The previous removeView() had not completed executing. Now it has.
}
+ boolean isSubWindow = false;
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
+ isSubWindow = true;
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
@@ -396,6 +399,19 @@ public void addView(View view, ViewGroup.LayoutParams params,
view.setLayoutParams(wparams);
+ int visibleRootCount = 0;
+ if (!isSubWindow) {
+ for (int i = mRoots.size() - 1; i >= 0; --i) {
+ View root_view = mRoots.get(i).getView();
+ if (root_view != null && root_view.getVisibility() == View.VISIBLE) {
+ visibleRootCount++;
+ }
+ }
+ }
+ if (isSubWindow || visibleRootCount > 1) {
+ ScrollOptimizer.disableOptimizer(true);
+ }
+
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
@@ -522,6 +538,18 @@ void doRemoveView(ViewRootImpl root) {
final View view = mViews.remove(index);
mDyingViews.remove(view);
}
+
+ int visibleRootCount = 0;
+ for (int i = mRoots.size() - 1; i >= 0; --i) {
+ View root_view = mRoots.get(i).getView();
+ if (root_view != null && root_view.getVisibility() == View.VISIBLE) {
+ visibleRootCount++;
+ }
+ }
+ if (visibleRootCount == 1) {
+ ScrollOptimizer.disableOptimizer(false);
+ }
+
allViewsRemoved = mRoots.isEmpty();
}
if (ThreadedRenderer.sTrimForeground) {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index b5a742bfb2eb..ef4a77a04fd8 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -73,6 +73,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.text.style.SuggestionSpan;
+import android.util.BoostFramework;
import android.util.Log;
import android.util.Pools.Pool;
import android.util.Pools.SimplePool;
@@ -282,6 +283,11 @@ public final class InputMethodManager {
*/
private static final String SUBTYPE_MODE_VOICE = "voice";
+ //Perf
+ static BoostFramework mPerfBoost = null;
+ static boolean IME_BOOST_ENABLED = false;
+ static boolean isImeBoostPropertyRead = false;
+
/**
* Provide this to {@link IInputMethodManager#startInputOrWindowGainedFocus(
* int, IInputMethodClient, IBinder, int, int, int, EditorInfo, IInputContext, int)} to receive
@@ -657,6 +663,20 @@ public boolean startInput(@StartInputReason int startInputReason, View focusedVi
ImeTracing.getInstance().triggerClientDump(
"InputMethodManager.DelegateImpl#startInput", InputMethodManager.this,
null /* icProto */);
+
+ if (isImeBoostPropertyRead == false) {
+ mPerfBoost = new BoostFramework();
+
+ if (mPerfBoost != null) {
+ IME_BOOST_ENABLED = Boolean.parseBoolean(mPerfBoost.perfGetProp("ro.vendor.qti.sys.fw.use_ime_boost", "false"));
+ }
+ isImeBoostPropertyRead = true;
+ }
+
+ if (IME_BOOST_ENABLED == true && mPerfBoost != null) {
+ mPerfBoost.perfEvent(BoostFramework.VENDOR_HINT_IME_LAUNCH_EVENT, null);
+ }
+
synchronized (mH) {
mCurrentTextBoxAttribute = null;
mCompletions = null;
diff --git a/core/java/android/webkit/ConsoleMessage.java b/core/java/android/webkit/ConsoleMessage.java
index 5474557c9998..89cb6b2761be 100644
--- a/core/java/android/webkit/ConsoleMessage.java
+++ b/core/java/android/webkit/ConsoleMessage.java
@@ -68,4 +68,4 @@ public String sourceId() {
public int lineNumber() {
return mLineNumber;
}
-};
+}
diff --git a/core/java/android/webkit/ValueCallback.java b/core/java/android/webkit/ValueCallback.java
index 5c7d97fc5d8c..3d5bb4922a77 100644
--- a/core/java/android/webkit/ValueCallback.java
+++ b/core/java/android/webkit/ValueCallback.java
@@ -25,4 +25,4 @@ public interface ValueCallback {
* @param value The value.
*/
public void onReceiveValue(T value);
-};
+}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 0b0bfb1ddbe9..20333f72e6f9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -684,6 +684,7 @@ public abstract class AbsListView extends AdapterView implements Te
private int mMinimumVelocity;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051740)
private int mMaximumVelocity;
+ private int mDecacheThreshold;
private float mVelocityScale = 1.0f;
final boolean[] mIsScrap = new boolean[1];
@@ -994,6 +995,7 @@ private void initAbsListView() {
mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mDecacheThreshold = mMaximumVelocity / 2;
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
@@ -4811,7 +4813,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);
}
@@ -4827,6 +4829,11 @@ public void run() {
// Use AbsListView#fling(int) instead
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
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);
@@ -4907,6 +4914,10 @@ void startScroll(int distance, int duration, boolean linear,
// To interrupt a fling early you should use smoothScrollBy(0,0) instead
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void endFling() {
+ endFling(true);
+ }
+
+ void endFling(boolean clearCache) {
mTouchMode = TOUCH_MODE_REST;
removeCallbacks(this);
@@ -4915,7 +4926,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 6281ee9d05d1..3946fb621720 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -1013,7 +1013,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/OverScroller.java b/core/java/android/widget/OverScroller.java
index 1683878cd8b2..93dbfa07fc4c 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
+import android.util.BoostFramework.ScrollOptimizer;
import android.util.Log;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
@@ -361,6 +362,7 @@ public void startScroll(int startX, int startY, int dx, int dy) {
* @param duration Duration of the scroll in milliseconds.
*/
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ ScrollOptimizer.setFlingFlag(ScrollOptimizer.FLING_END);
mMode = SCROLL_MODE;
mScrollerX.startScroll(startX, dx, duration);
mScrollerY.startScroll(startY, dy, duration);
diff --git a/core/java/android/window/TransitionFilter.java b/core/java/android/window/TransitionFilter.java
index db15145b0a1e..e62d5c95a1f8 100644
--- a/core/java/android/window/TransitionFilter.java
+++ b/core/java/android/window/TransitionFilter.java
@@ -296,7 +296,7 @@ public String toString() {
out.append((i == 0 ? "" : ",") + TransitionInfo.modeToString(mModes[i]));
}
}
- out.append("]").toString();
+ out.append("]");
out.append(" flags=" + TransitionInfo.flagsToString(mFlags));
out.append(" mustBeTask=" + mMustBeTask);
out.append(" order=" + containerOrderToString(mOrder));
diff --git a/core/java/com/android/internal/app/ActivityTrigger.java b/core/java/com/android/internal/app/ActivityTrigger.java
new file mode 100644
index 000000000000..dbcb13f49ef5
--- /dev/null
+++ b/core/java/com/android/internal/app/ActivityTrigger.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2015-2017, 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 com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.util.Log;
+
+public class ActivityTrigger
+{
+ private static final String TAG = "ActivityTrigger";
+
+ /** @hide */
+ public ActivityTrigger() {
+ //Log.d(TAG, "ActivityTrigger initialized");
+ }
+
+ /** @hide */
+ protected void finalize() {
+ native_at_deinit();
+ }
+
+ /** @hide */
+ public void activityStartTrigger(ApplicationInfo appInfo, int pid) {
+ int reserved =0;
+ String activity = null;
+ activity = appInfo.packageName + "/" + appInfo.processName + "/" +
+ appInfo.longVersionCode + "/" + pid;
+ native_at_startApp(activity, reserved);
+ }
+
+ /** @hide */
+ public void activityResumeTrigger(Intent intent, ActivityInfo acInfo,
+ ApplicationInfo appInfo, boolean IsInFullScreen) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+
+ if (cn != null)
+ activity = cn.flattenToString() + "/" + appInfo.versionCode;
+ native_at_resumeActivity(activity);
+ }
+
+ public void activityPauseTrigger(Intent intent, ActivityInfo acInfo, ApplicationInfo appInfo) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+ Log.d(TAG, "ActivityTrigger activityPauseTrigger ");
+ if (null != cn && null != appInfo)
+ activity = cn.flattenToString() + "/" + appInfo.versionCode;
+ native_at_pauseActivity(activity);
+ }
+
+ public void activityStopTrigger(Intent intent, ActivityInfo acInfo, ApplicationInfo appInfo) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+ Log.d(TAG, "ActivityTrigger activityStopTrigger ");
+ if (null != cn && null != appInfo)
+ activity = cn.flattenToString() + "/" + appInfo.versionCode;
+ native_at_stopActivity(activity);
+ }
+
+ public float activityMiscTrigger(int func, String activity, int flag, int type) {
+ return native_at_miscActivity(func, activity, flag, type);
+ }
+
+ private native int native_at_startActivity(String activity, int flags);
+ private native int native_at_startApp(String activity, int flags);
+ private native void native_at_resumeActivity(String activity);
+ private native void native_at_pauseActivity(String activity);
+ private native void native_at_stopActivity(String activity);
+ private native void native_at_deinit();
+ private native float native_at_miscActivity(int func, String activity, int flag, int type);
+}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 30da4b470ab6..88447daf7338 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -58,11 +58,12 @@ interface IAppOpsService {
SyncNotedAppOp noteProxyOperation(int code, in AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation);
- SyncNotedAppOp startProxyOperation(int code, in AttributionSource attributionSource,
- boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
- boolean shouldCollectMessage, boolean skipProxyOperation, int proxyAttributionFlags,
- int proxiedAttributionFlags, int attributionChainId);
- void finishProxyOperation(int code, in AttributionSource attributionSource,
+ SyncNotedAppOp startProxyOperation(IBinder clientId, int code,
+ in AttributionSource attributionSource, boolean startIfModeDefault,
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+ boolean skipProxyOperation, int proxyAttributionFlags, int proxiedAttributionFlags,
+ int attributionChainId);
+ void finishProxyOperation(IBinder clientId, int code, in AttributionSource attributionSource,
boolean skipProxyOperation);
// Remaining methods are only used in Java.
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 629a1b36b9e6..c1fa18f04922 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -189,4 +189,7 @@ interface IBatteryStats {
void resetBattery(boolean forceUpdate);
/** Exposed as a test API. */
void suspendBatteryInput();
+
+ /** {@hide} */
+ void resetStatistics();
}
diff --git a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
index 5f4a9cd5141e..473134ea46f3 100644
--- a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
+++ b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
@@ -172,14 +172,14 @@ public boolean start(Activity activity, Bundle options) {
@Override
public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
- prepareIntentForCrossProfileLaunch(mResolvedIntent, userId);
+ TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId);
activity.startActivityAsCaller(mResolvedIntent, options, false, userId);
return true;
}
@Override
public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
- prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier());
+ TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier());
activity.startActivityAsUser(mResolvedIntent, options, user);
return false;
}
@@ -224,13 +224,6 @@ public DisplayResolveInfo[] newArray(int size) {
}
};
- private static void prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId) {
- final int currentUserId = UserHandle.myUserId();
- if (targetUserId != currentUserId) {
- intent.fixUris(currentUserId);
- }
- }
-
private DisplayResolveInfo(Parcel in) {
mDisplayLabel = in.readCharSequence();
mExtendedInfo = in.readCharSequence();
diff --git a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
index 264e4f76d35d..4b9b7cb98dac 100644
--- a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
+++ b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
@@ -232,6 +232,7 @@ public boolean startAsCaller(ResolverActivity activity, Bundle options, int user
}
intent.setComponent(mChooserTarget.getComponentName());
intent.putExtras(mChooserTarget.getIntentExtras());
+ TargetInfo.prepareIntentForCrossProfileLaunch(intent, userId);
// Important: we will ignore the target security checks in ActivityManager
// if and only if the ChooserTarget's target package is the same package
diff --git a/core/java/com/android/internal/app/chooser/TargetInfo.java b/core/java/com/android/internal/app/chooser/TargetInfo.java
index f56ab17cb059..7bb7ddc65c6d 100644
--- a/core/java/com/android/internal/app/chooser/TargetInfo.java
+++ b/core/java/com/android/internal/app/chooser/TargetInfo.java
@@ -130,4 +130,15 @@ public interface TargetInfo {
* @return true if this target should be pinned to the front by the request of the user
*/
boolean isPinned();
+
+ /**
+ * Fix the URIs in {@code intent} if cross-profile sharing is required. This should be called
+ * before launching the intent as another user.
+ */
+ static void prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId) {
+ final int currentUserId = UserHandle.myUserId();
+ if (targetUserId != currentUserId) {
+ intent.fixUris(currentUserId);
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/procstats/AssociationState.java b/core/java/com/android/internal/app/procstats/AssociationState.java
index 97f4b0fc8733..a21a84261ae0 100644
--- a/core/java/com/android/internal/app/procstats/AssociationState.java
+++ b/core/java/com/android/internal/app/procstats/AssociationState.java
@@ -59,6 +59,7 @@ public final class AssociationState {
/**
* The state of the source process of an association.
*/
+ @SuppressWarnings("ParcelableCreator")
public static final class SourceState implements Parcelable {
private @NonNull final ProcessStats mProcessStats;
private @Nullable final AssociationState mAssociationState;
diff --git a/core/java/com/android/internal/bootleggers/hardware/HIDLHelper.java b/core/java/com/android/internal/bootleggers/hardware/HIDLHelper.java
new file mode 100644
index 000000000000..d67274feb8da
--- /dev/null
+++ b/core/java/com/android/internal/bootleggers/hardware/HIDLHelper.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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.
+ * 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.bootleggers.hardware;
+
+import android.util.Range;
+
+import java.util.ArrayList;
+
+class HIDLHelper {
+
+ static TouchscreenGesture[] fromHIDLGestures(
+ ArrayList gestures) {
+ int size = gestures.size();
+ TouchscreenGesture[] r = new TouchscreenGesture[size];
+ for (int i = 0; i < size; i++) {
+ vendor.lineage.touch.V1_0.Gesture g = gestures.get(i);
+ r[i] = new TouchscreenGesture(g.id, g.name, g.keycode);
+ }
+ return r;
+ }
+
+ static vendor.lineage.touch.V1_0.Gesture toHIDLGesture(TouchscreenGesture gesture) {
+ vendor.lineage.touch.V1_0.Gesture g = new vendor.lineage.touch.V1_0.Gesture();
+ g.id = gesture.id;
+ g.name = gesture.name;
+ g.keycode = gesture.keycode;
+ return g;
+ }
+
+}
diff --git a/core/java/com/android/internal/bootleggers/hardware/LineageHardwareManager.java b/core/java/com/android/internal/bootleggers/hardware/LineageHardwareManager.java
new file mode 100644
index 000000000000..a88e23b5107f
--- /dev/null
+++ b/core/java/com/android/internal/bootleggers/hardware/LineageHardwareManager.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2015-2016 The CyanogenMod Project
+ * 2017-2019 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.
+ * 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.bootleggers.hardware;
+
+import android.content.Context;
+import android.hidl.base.V1_0.IBase;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Range;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+import com.android.internal.bootleggers.hardware.HIDLHelper;
+
+import vendor.lineage.touch.V1_0.IGloveMode;
+import vendor.lineage.touch.V1_0.IKeyDisabler;
+import vendor.lineage.touch.V1_0.IStylusMode;
+import vendor.lineage.touch.V1_0.ITouchscreenGesture;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.IllegalArgumentException;
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Manages access to LineageOS hardware extensions
+ *
+ *
+ * This manager requires the HARDWARE_ABSTRACTION_ACCESS permission.
+ *
+ * To get the instance of this class, utilize LineageHardwareManager#getInstance(Context context)
+ */
+public final class LineageHardwareManager {
+ private static final String TAG = "LineageHardwareManager";
+
+ // The VisibleForTesting annotation is to ensure Proguard doesn't remove these
+ // fields, as they might be used via reflection. When the @Keep annotation in
+ // the support library is properly handled in the platform, we should change this.
+
+ /**
+ * High touch sensitivity for touch panels
+ */
+ @VisibleForTesting
+ public static final int FEATURE_HIGH_TOUCH_SENSITIVITY = 0x10;
+
+ /**
+ * Hardware navigation key disablement
+ */
+ @VisibleForTesting
+ public static final int FEATURE_KEY_DISABLE = 0x20;
+
+ /**
+ * Touchscreen hovering
+ */
+ @VisibleForTesting
+ public static final int FEATURE_TOUCH_HOVERING = 0x800;
+
+ /**
+ * Touchscreen gesture
+ */
+ @VisibleForTesting
+ public static final int FEATURE_TOUCHSCREEN_GESTURES = 0x80000;
+
+ private static final List BOOLEAN_FEATURES = Arrays.asList(
+ FEATURE_HIGH_TOUCH_SENSITIVITY,
+ FEATURE_KEY_DISABLE,
+ FEATURE_TOUCH_HOVERING
+ );
+
+ private static LineageHardwareManager sLineageHardwareManagerInstance;
+
+ private Context mContext;
+
+ // HIDL hals
+ private HashMap mHIDLMap = new HashMap();
+
+ /**
+ * @hide to prevent subclassing from outside of the framework
+ */
+ private LineageHardwareManager(Context context) {
+ Context appContext = context.getApplicationContext();
+ if (appContext != null) {
+ mContext = appContext;
+ } else {
+ mContext = context;
+ }
+ }
+
+ /**
+ * Determine if a Lineage Hardware feature is supported on this device
+ *
+ * @param feature The Lineage Hardware feature to query
+ *
+ * @return true if the feature is supported, false otherwise.
+ */
+ public boolean isSupported(int feature) {
+ return isSupportedHIDL(feature);
+ }
+
+ private boolean isSupportedHIDL(int feature) {
+ if (!mHIDLMap.containsKey(feature)) {
+ mHIDLMap.put(feature, getHIDLService(feature));
+ }
+ return mHIDLMap.get(feature) != null;
+ }
+
+ private IBase getHIDLService(int feature) {
+ try {
+ switch (feature) {
+ case FEATURE_HIGH_TOUCH_SENSITIVITY:
+ return IGloveMode.getService(true);
+ case FEATURE_KEY_DISABLE:
+ return IKeyDisabler.getService(true);
+ case FEATURE_TOUCH_HOVERING:
+ return IStylusMode.getService(true);
+ case FEATURE_TOUCHSCREEN_GESTURES:
+ return ITouchscreenGesture.getService(true);
+ }
+ } catch (NoSuchElementException | RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Get or create an instance of the {@link com.android.internal.custom.hardware.LineageHardwareManager}
+ * @param context
+ * @return {@link LineageHardwareManager}
+ */
+ public static LineageHardwareManager getInstance(Context context) {
+ if (sLineageHardwareManagerInstance == null) {
+ sLineageHardwareManagerInstance = new LineageHardwareManager(context);
+ }
+ return sLineageHardwareManagerInstance;
+ }
+
+ /**
+ * Determine if the given feature is enabled or disabled.
+ *
+ * Only used for features which have simple enable/disable controls.
+ *
+ * @param feature the Lineage Hardware feature to query
+ *
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean get(int feature) {
+ if (!BOOLEAN_FEATURES.contains(feature)) {
+ throw new IllegalArgumentException(feature + " is not a boolean");
+ }
+
+ try {
+ if (isSupportedHIDL(feature)) {
+ IBase obj = mHIDLMap.get(feature);
+ switch (feature) {
+ case FEATURE_HIGH_TOUCH_SENSITIVITY:
+ IGloveMode gloveMode = (IGloveMode) obj;
+ return gloveMode.isEnabled();
+ case FEATURE_KEY_DISABLE:
+ IKeyDisabler keyDisabler = (IKeyDisabler) obj;
+ return keyDisabler.isEnabled();
+ case FEATURE_TOUCH_HOVERING:
+ IStylusMode stylusMode = (IStylusMode) obj;
+ return stylusMode.isEnabled();
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Enable or disable the given feature
+ *
+ * Only used for features which have simple enable/disable controls.
+ *
+ * @param feature the Lineage Hardware feature to set
+ * @param enable true to enable, false to disale
+ *
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean set(int feature, boolean enable) {
+ if (!BOOLEAN_FEATURES.contains(feature)) {
+ throw new IllegalArgumentException(feature + " is not a boolean");
+ }
+
+ try {
+ if (isSupportedHIDL(feature)) {
+ IBase obj = mHIDLMap.get(feature);
+ switch (feature) {
+ case FEATURE_HIGH_TOUCH_SENSITIVITY:
+ IGloveMode gloveMode = (IGloveMode) obj;
+ return gloveMode.setEnabled(enable);
+ case FEATURE_KEY_DISABLE:
+ IKeyDisabler keyDisabler = (IKeyDisabler) obj;
+ return keyDisabler.setEnabled(enable);
+ case FEATURE_TOUCH_HOVERING:
+ IStylusMode stylusMode = (IStylusMode) obj;
+ return stylusMode.setEnabled(enable);
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * @return a list of available touchscreen gestures on the devices
+ */
+ public TouchscreenGesture[] getTouchscreenGestures() {
+ try {
+ if (isSupportedHIDL(FEATURE_TOUCHSCREEN_GESTURES)) {
+ ITouchscreenGesture touchscreenGesture = (ITouchscreenGesture)
+ mHIDLMap.get(FEATURE_TOUCHSCREEN_GESTURES);
+ return HIDLHelper.fromHIDLGestures(touchscreenGesture.getSupportedGestures());
+ }
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return true if setting the activation status was successful
+ */
+ public boolean setTouchscreenGestureEnabled(
+ TouchscreenGesture gesture, boolean state) {
+ try {
+ if (isSupportedHIDL(FEATURE_TOUCHSCREEN_GESTURES)) {
+ ITouchscreenGesture touchscreenGesture = (ITouchscreenGesture)
+ mHIDLMap.get(FEATURE_TOUCHSCREEN_GESTURES);
+ return touchscreenGesture.setGestureEnabled(
+ HIDLHelper.toHIDLGesture(gesture), state);
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+}
diff --git a/core/java/com/android/internal/bootleggers/hardware/TouchscreenGesture.aidl b/core/java/com/android/internal/bootleggers/hardware/TouchscreenGesture.aidl
new file mode 100644
index 000000000000..e7853bf403b5
--- /dev/null
+++ b/core/java/com/android/internal/bootleggers/hardware/TouchscreenGesture.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ * 2017 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.
+ * 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.bootleggers.hardware;
+
+parcelable TouchscreenGesture;
diff --git a/core/java/com/android/internal/bootleggers/hardware/TouchscreenGesture.java b/core/java/com/android/internal/bootleggers/hardware/TouchscreenGesture.java
new file mode 100644
index 000000000000..764aab7967b7
--- /dev/null
+++ b/core/java/com/android/internal/bootleggers/hardware/TouchscreenGesture.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ * 2017 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.
+ * 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.bootleggers.hardware;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Touchscreen gestures API
+ *
+ * A device may implement several touchscreen gestures for use while
+ * the display is turned off, such as drawing alphabets and shapes.
+ * These gestures can be interpreted by userspace to activate certain
+ * actions and launch certain apps, such as to skip music tracks,
+ * to turn on the flashlight, or to launch the camera app.
+ *
+ * This *should always* be supported by the hardware directly.
+ * A lot of recent touch controllers have a firmware option for this.
+ *
+ * This API provides support for enumerating the gestures
+ * supported by the touchscreen.
+ *
+ * A TouchscreenGesture is referenced by it's identifier and carries an
+ * associated name (up to the user to translate this value).
+ */
+public class TouchscreenGesture implements Parcelable {
+
+ public final int id;
+ public final String name;
+ public final int keycode;
+
+ public TouchscreenGesture(int id, String name, int keycode) {
+ this.id = id;
+ this.name = name;
+ this.keycode = keycode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(id);
+ parcel.writeString(name);
+ parcel.writeInt(keycode);
+ }
+
+ /** @hide */
+ public static final Parcelable.Creator CREATOR =
+ new Parcelable.Creator() {
+
+ public TouchscreenGesture createFromParcel(Parcel in) {
+ return new TouchscreenGesture(in.readInt(), in.readString(), in.readInt());
+ }
+
+ @Override
+ public TouchscreenGesture[] newArray(int size) {
+ return new TouchscreenGesture[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index ec2bc7cde1a0..a8e39eb5e994 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3634,6 +3634,7 @@ public T stopObject(String name, long elapsedRealtimeMs) {
public abstract T instantiateObject();
}
+ @SuppressWarnings("ParcelableCreator")
public static class ControllerActivityCounterImpl extends ControllerActivityCounter
implements Parcelable {
private final Clock mClock;
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 0a29fc5285a5..eb62cb07ee68 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -735,7 +735,7 @@ protected long getElapsedRealtimeMicro() {
}
protected boolean shouldRecordDetailedData() {
- return mRandom.nextInt() % mPeriodicSamplingInterval == 0;
+ return mRandom.nextInt(mPeriodicSamplingInterval) == 0;
}
/**
diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java
index e9d55db3a5b4..1276fb980799 100644
--- a/core/java/com/android/internal/os/BinderLatencyObserver.java
+++ b/core/java/com/android/internal/os/BinderLatencyObserver.java
@@ -236,7 +236,7 @@ protected boolean shouldCollect(LatencyDims dims) {
}
protected boolean shouldKeepSample() {
- return mRandom.nextInt() % mPeriodicSamplingInterval == 0;
+ return mRandom.nextInt(mPeriodicSamplingInterval) == 0;
}
/** Updates the sampling interval. */
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..8902337f3ebb
--- /dev/null
+++ b/core/java/com/android/internal/os/DeviceKeyHandler.java
@@ -0,0 +1,31 @@
+/*
+ * 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/KernelCpuUidTimeReader.java b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
index c801be0ce3e7..7ea55dcbe67f 100644
--- a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
+++ b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Build;
import android.os.StrictMode;
import android.util.IntArray;
import android.util.Slog;
@@ -497,7 +498,7 @@ private void processUidDelta(@Nullable Callback cb) {
// Unit is 10ms.
mDeltaTimes[i] = mCurTimes[i] - lastTimes[i];
if (mDeltaTimes[i] < 0) {
- Slog.e(mTag, "Negative delta from freq time for uid: " + uid
+ if (DEBUG) Slog.e(mTag, "Negative delta from freq time for uid: " + uid
+ ", delta: " + mDeltaTimes[i]);
return;
}
@@ -530,7 +531,11 @@ void readDeltaImpl(@Nullable Callback cb, boolean forceRead) {
CharBuffer buf;
while ((buf = iter.nextLine()) != null) {
if (asLongs(buf, mBuffer) != mBuffer.length) {
- Slog.wtf(mTag, "Invalid line: " + buf.toString());
+ if (Build.IS_ENG) {
+ Slog.wtf(mTag, "Invalid line: " + buf.toString());
+ } else {
+ Slog.w(mTag, "Invalid line: " + buf.toString());
+ }
continue;
}
processUidDelta(cb);
@@ -673,7 +678,7 @@ private void processUidDelta(@Nullable Callback cb) {
cb.onUidCpuTime(uid, delta);
}
} else if (delta < 0) {
- Slog.e(mTag, "Negative delta from active time for uid: " + uid
+ if (DEBUG) Slog.e(mTag, "Negative delta from active time for uid: " + uid
+ ", delta: " + delta);
}
}
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index 2805dccffe50..0645eb7f0835 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -290,7 +290,7 @@ protected long getSystemUptimeMillis() {
}
protected boolean shouldCollectDetailedData() {
- return ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0;
+ return ThreadLocalRandom.current().nextInt(mSamplingInterval) == 0;
}
private static class DispatchSession {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index ca1ae194cb12..319c091f4237 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -187,6 +187,12 @@ private static void preloadSharedLibraries() {
System.loadLibrary("android");
System.loadLibrary("compiler_rt");
System.loadLibrary("jnigraphics");
+
+ try {
+ System.loadLibrary("qti_performance");
+ } catch (UnsatisfiedLinkError e) {
+ Log.e(TAG, "Couldn't load qti_performance");
+ }
}
native private static void nativePreloadAppProcessHALs();
diff --git a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
index 205c5fd735ea..ea5ab3b4155a 100644
--- a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
+++ b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
@@ -67,6 +67,9 @@ public void register() {
r.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE),
false, this, UserHandle.USER_ALL);
+ r.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BACK_GESTURE_HAPTIC),
+ false, this, UserHandle.USER_ALL);
DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI,
runnable -> mMainHandler.post(runnable),
@@ -94,6 +97,15 @@ public int getRightSensitivity(Resources userRes) {
return getSensitivity(userRes, Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT);
}
+ public boolean getEdgeHaptic() {
+ return (Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.BACK_GESTURE_HAPTIC, 0,
+ UserHandle.USER_CURRENT) == 1 &&
+ Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 0,
+ UserHandle.USER_CURRENT) == 1);
+ }
+
public boolean areNavigationButtonForcedVisible() {
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) == 0;
@@ -114,4 +126,6 @@ private int getSensitivity(Resources userRes, String side) {
mContext.getContentResolver(), side, 1.0f, UserHandle.USER_CURRENT);
return (int) (inset * scale);
}
+
+
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 44cfe1aa4a79..dff07e9beeee 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -149,7 +149,7 @@ oneway interface IStatusBar
void showPinningEnterExitToast(boolean entering);
void showPinningEscapeToast();
- void showShutdownUi(boolean isReboot, String reason);
+ void showShutdownUi(boolean isReboot, String reason, boolean rebootCustom);
/**
* Used to show the authentication dialog (Biometrics, Device Credential).
@@ -322,4 +322,9 @@ oneway interface IStatusBar
/** Unregisters a nearby media devices provider. */
void unregisterNearbyMediaDevicesProvider(in INearbyMediaDevicesProvider provider);
+
+ /**
+ * Toggles flashlight of the device
+ */
+ void toggleCameraFlash();
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index ef8f2db5ff57..479ca17724a6 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -101,7 +101,7 @@ interface IStatusBarService
* These methods are needed for global actions control which the UI is shown in sysui.
*/
void shutdown();
- void reboot(boolean safeMode);
+ void reboot(boolean safeMode, String reason);
/** just restarts android without rebooting device. Used for some feature flags. */
void restart();
@@ -226,4 +226,9 @@ interface IStatusBarService
/** Unregisters a nearby media devices provider. */
void unregisterNearbyMediaDevicesProvider(in INearbyMediaDevicesProvider provider);
+
+ /**
+ * Toggles flashlight of the device
+ */
+ void toggleCameraFlash();
}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 8fcb6d5514d4..4b7b91c74f94 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -468,7 +468,7 @@ public void logAction(@Action int action, int duration) {
boolean shouldSample;
int traceThreshold;
synchronized (mLock) {
- shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0;
+ shouldSample = ThreadLocalRandom.current().nextInt(mSamplingInterval) == 0;
traceThreshold = mTraceThresholdPerAction[action];
}
diff --git a/core/java/com/android/internal/util/awaken/FileUtils.java b/core/java/com/android/internal/util/awaken/FileUtils.java
new file mode 100644
index 000000000000..ee663668b9f5
--- /dev/null
+++ b/core/java/com/android/internal/util/awaken/FileUtils.java
@@ -0,0 +1,125 @@
+/*
+ * 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.awaken;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+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;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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 isFileReadable(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 isFileWritable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canWrite();
+ }
+}
diff --git a/core/java/com/android/internal/util/bootleg/Action.java b/core/java/com/android/internal/util/bootleg/Action.java
new file mode 100644
index 000000000000..f49534c7317a
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/Action.java
@@ -0,0 +1,307 @@
+/*
+* 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.bootleg;
+
+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 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("gzospActions:", "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("gzospActions:", "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;
+ }
+ 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/bootleg/ActionConfig.java b/core/java/com/android/internal/util/bootleg/ActionConfig.java
new file mode 100644
index 000000000000..36b6e19eea7b
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/ActionConfig.java
@@ -0,0 +1,81 @@
+/*
+* 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.bootleg;
+
+public class ActionConfig {
+
+ private String mClickAction;
+ private String mClickActionDescription;
+ private String mLongpressAction;
+ private String mLongpressActionDescription;
+ private String mIconUri;
+
+ public ActionConfig(String clickAction, String clickActionDescription,
+ String longpressAction, String longpressActionDescription, String iconUri) {
+ mClickAction = clickAction;
+ mClickActionDescription = clickActionDescription;
+ mLongpressAction = longpressAction;
+ mLongpressActionDescription = longpressActionDescription;
+ mIconUri = iconUri;
+ }
+
+ @Override
+ public String toString() {
+ return mClickActionDescription;
+ }
+
+ public String getClickAction() {
+ return mClickAction;
+ }
+
+ public String getClickActionDescription() {
+ return mClickActionDescription;
+ }
+
+ public String getLongpressAction() {
+ return mLongpressAction;
+ }
+
+ public String getLongpressActionDescription() {
+ return mLongpressActionDescription;
+ }
+
+ public String getIcon() {
+ return mIconUri;
+ }
+
+ public void setClickAction(String action) {
+ mClickAction = action;
+ }
+
+ public void setClickActionDescription(String description) {
+ mClickActionDescription = description;
+ }
+
+ public void setLongpressAction(String action) {
+ mLongpressAction = action;
+ }
+
+ public void setLongpressActionDescription(String description) {
+ mLongpressActionDescription = description;
+ }
+
+ public void setIcon(String iconUri) {
+ mIconUri = iconUri;
+ }
+
+}
diff --git a/core/java/com/android/internal/util/bootleg/ActionConstants.java b/core/java/com/android/internal/util/bootleg/ActionConstants.java
new file mode 100644
index 000000000000..fa947c30bbe3
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/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.bootleg;
+
+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/bootleg/ActionHelper.java b/core/java/com/android/internal/util/bootleg/ActionHelper.java
new file mode 100644
index 000000000000..0077d1711e78
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/ActionHelper.java
@@ -0,0 +1,162 @@
+/*
+* 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.bootleg;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.Settings;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+public class ActionHelper {
+
+ private static final String SYSTEMUI_METADATA_NAME = "com.android.systemui";
+
+ // General methods to retrieve the correct icon for the respective action.
+ public static Drawable getButtonIconImage(Context context,
+ String clickAction, String customIcon) {
+ int resId = -1;
+ Drawable d = null;
+ PackageManager pm = context.getPackageManager();
+ if (pm == null) {
+ return null;
+ }
+
+ Resources systemUiResources;
+ try {
+ systemUiResources = pm.getResourcesForApplication(SYSTEMUI_METADATA_NAME);
+ } catch (Exception e) {
+ Log.e("ButtonsHelper:", "can't access systemui resources",e);
+ return null;
+ }
+
+ if (!clickAction.startsWith("**")) {
+ try {
+ String extraIconPath = clickAction.replaceAll(".*?hasExtraIcon=", "");
+ if (extraIconPath != null && !extraIconPath.isEmpty()) {
+ File f = new File(Uri.parse(extraIconPath).getPath());
+ if (f.exists()) {
+ d = new BitmapDrawable(context.getResources(),
+ f.getAbsolutePath());
+ }
+ }
+ if (d == null) {
+ d = pm.getActivityIcon(Intent.parseUri(clickAction, 0));
+ }
+ } catch (NameNotFoundException e) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_null", null, null);
+ if (resId > 0) {
+ d = systemUiResources.getDrawable(resId);
+ return d;
+ }
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (customIcon != null && customIcon.startsWith(ActionConstants.SYSTEM_ICON_IDENTIFIER)) {
+ resId = systemUiResources.getIdentifier(customIcon.substring(
+ ActionConstants.SYSTEM_ICON_IDENTIFIER.length()), "drawable", "android");
+ if (resId > 0) {
+ return systemUiResources.getDrawable(resId);
+ }
+ } else if (customIcon != null && !customIcon.equals(ActionConstants.ICON_EMPTY)) {
+ File f = new File(Uri.parse(customIcon).getPath());
+ if (f.exists()) {
+ return new BitmapDrawable(context.getResources(),
+ ImageHelper.getRoundedCornerBitmap(
+ new BitmapDrawable(context.getResources(),
+ f.getAbsolutePath()).getBitmap()));
+ } else {
+ Log.e("ActionHelper:", "can't access custom icon image");
+ return null;
+ }
+ } else if (clickAction.startsWith("**")) {
+ resId = getActionSystemIcon(systemUiResources, clickAction);
+
+ if (resId > 0) {
+ return systemUiResources.getDrawable(resId);
+ }
+ }
+ return d;
+ }
+
+ private static int getActionSystemIcon(Resources systemUiResources, String clickAction) {
+ int resId = -1;
+
+ // ToDo: Add the resources to SystemUI.
+ if (clickAction.equals(ActionConstants.ACTION_HOME)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_home", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_BACK)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_back", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_RECENTS)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_recent", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_SEARCH)
+ || clickAction.equals(ActionConstants.ACTION_ASSIST)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_search", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_KEYGUARD_SEARCH)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_search_light", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_MENU)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_menu", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_MENU_BIG)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_menu_big", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_IME)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_ime_switcher", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_POWER)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_power", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_POWER_MENU)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_power_menu", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_VIB)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_vib", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_SILENT)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_silent", null, null);
+ } else if (clickAction.equals(ActionConstants.ACTION_VIB_SILENT)) {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_ring_vib_silent", null, null);
+ } else {
+ resId = systemUiResources.getIdentifier(
+ SYSTEMUI_METADATA_NAME + ":drawable/ic_sysbar_null", null, null);
+ }
+ return resId;
+ }
+
+}
diff --git a/core/java/com/android/internal/util/bootleg/AppHelper.java b/core/java/com/android/internal/util/bootleg/AppHelper.java
new file mode 100644
index 000000000000..217bb4d1dbcc
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/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.bootleg;
+
+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/bootleg/BootlegUtils.java b/core/java/com/android/internal/util/bootleg/BootlegUtils.java
new file mode 100644
index 000000000000..63931a1649cf
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/BootlegUtils.java
@@ -0,0 +1,248 @@
+/*
+ * 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.bootleg;
+
+import android.app.ActivityManager;
+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.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.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.view.DisplayInfo;
+import android.util.DisplayMetrics;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+
+import java.util.List;
+import java.util.Locale;
+
+public class BootlegUtils {
+
+ private static int sDeviceType = -1;
+ private static final int DEVICE_PHONE = 0;
+ private static final int DEVICE_HYBRID = 1;
+ private static final int DEVICE_TABLET = 2;
+
+ public static boolean isChineseLanguage() {
+ return Resources.getSystem().getConfiguration().locale.getLanguage().startsWith(
+ Locale.CHINESE.getLanguage());
+ }
+
+ 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 boolean isWifiOnly(Context context) {
+ ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ final Network activeNetwork = cm.getActiveNetwork();
+ if (activeNetwork == null) {
+ return true;
+ }
+ final NetworkCapabilities networkCapabilities =
+ cm.getNetworkCapabilities(activeNetwork);
+ if (networkCapabilities == null) {
+ return true;
+ }
+ return (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false);
+ }
+
+ 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 isPackageAvailable(Context context, String pkg) {
+ return isPackageInstalled(context, pkg, false);
+ }
+
+ private static int getScreenType(Context context) {
+ if (sDeviceType == -1) {
+ WindowManager wm = (WindowManager) context.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) {
+ // 0-599dp: "phone" UI with a separate status & navigation bar
+ sDeviceType = DEVICE_PHONE;
+ } else if (shortSizeDp < 720) {
+ // 600-719dp: "phone" UI with modifications for larger screens
+ sDeviceType = DEVICE_HYBRID;
+ } else {
+ // 720dp: "tablet" UI with a single combined status & navigation bar
+ sDeviceType = DEVICE_TABLET;
+ }
+ }
+ return sDeviceType;
+ }
+
+ public static boolean isPhone(Context context) {
+ return getScreenType(context) == DEVICE_PHONE;
+ }
+
+ public static boolean isHybrid(Context context) {
+ return getScreenType(context) == DEVICE_HYBRID;
+ }
+
+ public static boolean isTablet(Context context) {
+ return getScreenType(context) == DEVICE_TABLET;
+ }
+
+ public static void switchScreenOff(Context ctx) {
+ PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
+ if (pm != null) {
+ pm.goToSleep(SystemClock.uptimeMillis());
+ }
+ }
+
+ // Check if device has a notch
+ public static boolean hasNotch(Context context) {
+ String displayCutout = context.getResources().getString(R.string.config_mainBuiltInDisplayCutout);
+ boolean maskDisplayCutout = context.getResources().getBoolean(R.bool.config_maskMainBuiltInDisplayCutout);
+ boolean displayCutoutExists = (!TextUtils.isEmpty(displayCutout) && !maskDisplayCutout);
+ return displayCutoutExists;
+ }
+
+ 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 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;
+ }
+
+ // Omni Switch Constants
+
+ /**
+ * Package name of the omnniswitch app
+ */
+ public static final String APP_PACKAGE_NAME = "org.omnirom.omniswitch";
+
+ /**
+ * Intent broadcast action for showing the omniswitch overlay
+ */
+ public static final String ACTION_SHOW_OVERLAY = APP_PACKAGE_NAME + ".ACTION_SHOW_OVERLAY";
+
+ /**
+ * Intent broadcast action for hiding the omniswitch overlay
+ */
+ public static final String ACTION_HIDE_OVERLAY = APP_PACKAGE_NAME + ".ACTION_HIDE_OVERLAY";
+
+ /**
+ * Intent broadcast action for toogle the omniswitch overlay
+ */
+ public static final String ACTION_TOGGLE_OVERLAY = APP_PACKAGE_NAME + ".ACTION_TOGGLE_OVERLAY";
+
+ /**
+ * Intent broadcast action for restoring the home stack
+ */
+ public static final String ACTION_RESTORE_HOME_STACK = APP_PACKAGE_NAME + ".ACTION_RESTORE_HOME_STACK";
+
+ /**
+ * Intent for launching the omniswitch settings actvity
+ */
+ public static Intent INTENT_LAUNCH_APP = new Intent(Intent.ACTION_MAIN)
+ .setClassName(APP_PACKAGE_NAME, APP_PACKAGE_NAME + ".SettingsActivity");
+
+}
diff --git a/core/java/com/android/internal/util/bootleg/ConfigSplitHelper.java b/core/java/com/android/internal/util/bootleg/ConfigSplitHelper.java
new file mode 100644
index 000000000000..f4a752128f86
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/ConfigSplitHelper.java
@@ -0,0 +1,98 @@
+/*
+* 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.bootleg;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class ConfigSplitHelper {
+
+ private static final String SETTINGS_METADATA_NAME = "com.android.settings";
+
+ public static ArrayList getActionConfigValues(Context context, String config,
+ String values, String entries, boolean isShortcut) {
+ // init vars to fill with them later the config values
+ int counter = 0;
+ ArrayList actionConfigList = new ArrayList();
+ ActionConfig actionConfig = null;
+
+ PackageManager pm = context.getPackageManager();
+ Resources settingsResources = null;
+ try {
+ settingsResources = pm.getResourcesForApplication(SETTINGS_METADATA_NAME);
+ } catch (Exception e) {
+ Log.e("ConfigSplitHelper", "can't access settings resources",e);
+ }
+
+ // Split out the config to work with and add to the list
+ for (String configValue : config.split("\\" + ActionConstants.ACTION_DELIMITER)) {
+ counter++;
+ if (counter == 1) {
+ actionConfig = new ActionConfig(configValue,
+ AppHelper.getProperSummary(context, pm, settingsResources,
+ configValue, values, entries), null, null, null);
+ }
+ if (counter == 2) {
+ if (isShortcut) {
+ actionConfig.setIcon(configValue);
+ actionConfigList.add(actionConfig);
+ //reset counter due that shortcut iteration of one action is finished
+ counter = 0;
+ } else {
+ actionConfig.setLongpressAction(configValue);
+ actionConfig.setLongpressActionDescription(
+ AppHelper.getProperSummary(context, pm, settingsResources,
+ configValue, values, entries));
+ }
+ }
+ if (counter == 3) {
+ actionConfig.setIcon(configValue);
+ actionConfigList.add(actionConfig);
+ //reset counter due that iteration of full config action is finished
+ counter = 0;
+ }
+ }
+
+ return actionConfigList;
+ }
+
+ public static String setActionConfig(
+ ArrayList actionConfigs, boolean isShortcut) {
+ String finalConfig = "";
+ ActionConfig actionConfig;
+
+ for (int i = 0; i < actionConfigs.size(); i++) {
+ if (i != 0) {
+ finalConfig += ActionConstants.ACTION_DELIMITER;
+ }
+ actionConfig = actionConfigs.get(i);
+ finalConfig += actionConfig.getClickAction() + ActionConstants.ACTION_DELIMITER;
+ if (!isShortcut) {
+ finalConfig += actionConfig.getLongpressAction()
+ + ActionConstants.ACTION_DELIMITER;
+ }
+ finalConfig += actionConfig.getIcon();
+ }
+
+ return finalConfig;
+ }
+
+}
diff --git a/core/java/com/android/internal/util/bootleg/Converter.java b/core/java/com/android/internal/util/bootleg/Converter.java
new file mode 100644
index 000000000000..34ebaed6ec4f
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/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.bootleg;
+
+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/bootleg/DeviceUtils.java b/core/java/com/android/internal/util/bootleg/DeviceUtils.java
new file mode 100644
index 000000000000..bf5ccbc0cf85
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/DeviceUtils.java
@@ -0,0 +1,180 @@
+/*
+* 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.bootleg;
+
+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.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.TetheringManager;
+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) {
+ TetheringManager tm = (TetheringManager) context.getSystemService(Context.TETHERING_SERVICE);
+ return (tm.getTetherableUsbRegexs().length != 0);
+ }
+
+ public static boolean deviceSupportsMobileData(Context context) {
+ ConnectivityManager cm =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ final Network activeNetwork = cm.getActiveNetwork();
+ if (activeNetwork == null) {
+ return false;
+ }
+ final NetworkCapabilities networkCapabilities =
+ cm.getNetworkCapabilities(activeNetwork);
+ if (networkCapabilities == null) {
+ return false;
+ }
+ return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
+ }
+
+ 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.isLteCdmaEvdoGsmWcdmaEnabled());
+ // || 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/bootleg/Helpers.java b/core/java/com/android/internal/util/bootleg/Helpers.java
new file mode 100644
index 000000000000..13cdf002e168
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/Helpers.java
@@ -0,0 +1,30 @@
+package com.android.internal.util.bootleg;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+
+public class Helpers {
+ // avoids hardcoding the tag
+ private static final String TAG = Thread.currentThread().getStackTrace()[1].getClassName();
+
+ public static void restartSystemUI(Context context) {
+ try {
+ ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ IActivityManager amn = ActivityManagerNative.getDefault();
+ context.stopService(new Intent().setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")));
+ am.killBackgroundProcesses("com.android.systemui");
+ for (ActivityManager.RunningAppProcessInfo app : am.getRunningAppProcesses()) {
+ if ("com.android.systemui".equals(app.processName)) {
+ amn.killApplicationProcess(app.processName, app.uid);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/core/java/com/android/internal/util/bootleg/ImageHelper.java b/core/java/com/android/internal/util/bootleg/ImageHelper.java
new file mode 100644
index 000000000000..b5994d6c2fab
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/ImageHelper.java
@@ -0,0 +1,147 @@
+/*
+* 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.bootleg;
+
+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.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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+}
diff --git a/core/java/com/android/internal/util/bootleg/KeyDisabler.java b/core/java/com/android/internal/util/bootleg/KeyDisabler.java
new file mode 100644
index 000000000000..8fb09dfb234b
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/KeyDisabler.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util.bootleg;
+
+/*
+ * Disable capacitive keys
+ *
+ * This is intended for use on devices in which the capacitive keys
+ * can be fully disabled for replacement with a soft navbar. You
+ * really should not be using this on a device with mechanical or
+ * otherwise visible-when-inactive keys
+ */
+
+public class KeyDisabler {
+
+ /*
+ * All HAF classes should export this boolean.
+ * Real implementations must, of course, return true
+ */
+
+ public static boolean isSupported() { return false; }
+
+ /*
+ * Are the keys currently blocked?
+ */
+
+ public static boolean isActive() {
+ return false;
+ }
+
+ /*
+ * Disable capacitive keys
+ */
+
+ public static boolean setActive(boolean state) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/core/java/com/android/internal/util/bootleg/ThemeUtils.java b/core/java/com/android/internal/util/bootleg/ThemeUtils.java
new file mode 100644
index 000000000000..f0cc4d635127
--- /dev/null
+++ b/core/java/com/android/internal/util/bootleg/ThemeUtils.java
@@ -0,0 +1,234 @@
+/*
+ * 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.bootleg;
+
+import static android.os.UserHandle.USER_SYSTEM;
+
+import android.util.PathParser;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Configuration;
+import android.database.Cursor;
+import android.graphics.Typeface;
+import android.graphics.Path;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class ThemeUtils {
+
+ public static final String TAG = "ThemeUtils";
+
+ public static final String FONT_KEY = "android.theme.customization.font";
+ public static final String ICON_SHAPE_KEY= "android.theme.customization.adaptive_icon_shape";
+
+ public static final Comparator OVERLAY_INFO_COMPARATOR =
+ Comparator.comparingInt(a -> a.priority);
+
+ private Context mContext;
+ private IOverlayManager mOverlayManager;
+ private PackageManager pm;
+ private Resources overlayRes;
+
+ public ThemeUtils(Context context) {
+ mContext = context;
+ mOverlayManager = IOverlayManager.Stub
+ .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE));
+ pm = context.getPackageManager();
+ }
+
+ public void setOverlayEnabled(String category, String packageName, String target) {
+ final String currentPackageName = getOverlayInfos(category, target).stream()
+ .filter(info -> info.isEnabled())
+ .map(info -> info.packageName)
+ .findFirst()
+ .orElse(null);
+
+ try {
+ if (target.equals(packageName)) {
+ mOverlayManager.setEnabled(currentPackageName, false, USER_SYSTEM);
+ } else {
+ mOverlayManager.setEnabledExclusiveInCategory(packageName,
+ USER_SYSTEM);
+ }
+
+ writeSettings(category, packageName, target.equals(packageName));
+
+ } catch (RemoteException e) {
+ }
+ }
+
+ public void writeSettings(String category, String packageName, boolean disable) {
+ final String overlayPackageJson = Settings.Secure.getStringForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, USER_SYSTEM);
+ JSONObject object;
+ try {
+ if (overlayPackageJson == null) {
+ object = new JSONObject();
+ } else {
+ object = new JSONObject(overlayPackageJson);
+ }
+ if (disable) {
+ if (object.has(category)) object.remove(category);
+ } else {
+ object.put(category, packageName);
+ }
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ object.toString(), USER_SYSTEM);
+ } catch (JSONException e) {
+ Log.e(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
+ }
+ }
+
+ public List getOverlayPackagesForCategory(String category) {
+ return getOverlayPackagesForCategory(category, "android");
+ }
+
+ public List getOverlayPackagesForCategory(String category, String target) {
+ List overlays = new ArrayList<>();
+ List mPkgs = new ArrayList<>();
+ overlays.add(target);
+ for (OverlayInfo info : getOverlayInfos(category, target)) {
+ if (category.equals(info.getCategory())) {
+ mPkgs.add(info.getPackageName());
+ }
+ }
+ Collections.sort(mPkgs);
+ overlays.addAll(mPkgs);
+ return overlays;
+ }
+
+ public List getOverlayInfos(String category) {
+ return getOverlayInfos(category, "android");
+ }
+
+ public List getOverlayInfos(String category, String target) {
+ final List filteredInfos = new ArrayList<>();
+ try {
+ List overlayInfos = mOverlayManager
+ .getOverlayInfosForTarget(target, USER_SYSTEM);
+ for (OverlayInfo overlayInfo : overlayInfos) {
+ if (category.equals(overlayInfo.category)) {
+ filteredInfos.add(overlayInfo);
+ }
+ }
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ filteredInfos.sort(OVERLAY_INFO_COMPARATOR);
+ return filteredInfos;
+ }
+
+ public List getFonts() {
+ final List fontlist = new ArrayList<>();
+ for (String overlayPackage : getOverlayPackagesForCategory(FONT_KEY)) {
+ try {
+ overlayRes = overlayPackage.equals("android") ? Resources.getSystem()
+ : pm.getResourcesForApplication(overlayPackage);
+ final String font = overlayRes.getString(
+ overlayRes.getIdentifier("config_bodyFontFamily",
+ "string", overlayPackage));
+ fontlist.add(Typeface.create(font, Typeface.NORMAL));
+ } catch (NameNotFoundException | NotFoundException e) {
+ // Do nothing
+ }
+ }
+ return fontlist;
+ }
+
+ public List getShapeDrawables() {
+ final List shapelist = new ArrayList<>();
+ for (String overlayPackage : getOverlayPackagesForCategory(ICON_SHAPE_KEY)) {
+ shapelist.add(createShapeDrawable(overlayPackage));
+ }
+ return shapelist;
+ }
+
+ public ShapeDrawable createShapeDrawable(String overlayPackage) {
+ try {
+ if (overlayPackage.equals("android")) {
+ overlayRes = Resources.getSystem();
+ } else {
+ if (overlayPackage.equals("default")) overlayPackage = "android";
+ overlayRes = pm.getResourcesForApplication(overlayPackage);
+ }
+ } catch (NameNotFoundException | NotFoundException e) {
+ // Do nothing
+ }
+ final String shape = overlayRes.getString(
+ overlayRes.getIdentifier("config_icon_mask",
+ "string", overlayPackage));
+ Path path = TextUtils.isEmpty(shape) ? null : PathParser.createPathFromPathData(shape);
+ PathShape pathShape = new PathShape(path, 100f, 100f);
+ ShapeDrawable shapeDrawable = new ShapeDrawable(pathShape);
+ int mThumbSize = (int) (mContext.getResources().getDisplayMetrics().density * 72);
+ shapeDrawable.setIntrinsicHeight(mThumbSize);
+ shapeDrawable.setIntrinsicWidth(mThumbSize);
+ return shapeDrawable;
+ }
+
+ public boolean isOverlayEnabled(String overlayPackage) {
+ try {
+ OverlayInfo info = mOverlayManager.getOverlayInfo(overlayPackage, USER_SYSTEM);
+ return info == null ? false : info.isEnabled();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean isDefaultOverlay(String category) {
+ for (String overlayPackage : getOverlayPackagesForCategory(category)) {
+ try {
+ OverlayInfo info = mOverlayManager.getOverlayInfo(overlayPackage, USER_SYSTEM);
+ if (info != null && info.isEnabled()) {
+ return false;
+ } else {
+ continue;
+ }
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ return true;
+ }
+}
diff --git a/core/java/com/android/internal/util/custom/PixelPropsUtils.java b/core/java/com/android/internal/util/custom/PixelPropsUtils.java
new file mode 100644
index 000000000000..3d566fc2c6df
--- /dev/null
+++ b/core/java/com/android/internal/util/custom/PixelPropsUtils.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2020 The Pixel Experience Project
+ * 2021-2022 crDroid Android 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;
+
+import android.app.Application;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class PixelPropsUtils {
+
+ private static final String TAG = PixelPropsUtils.class.getSimpleName();
+ private static final String DEVICE = "ro.product.device";
+ private static final boolean DEBUG = false;
+
+ private static final Map propsToChange;
+ private static final Map propsToChangePixel5;
+ private static final Map propsToChangePixel7Pro;
+ private static final Map propsToChangePixelXL;
+ private static final Map propsToChangeROG1;
+ private static final Map propsToChangeROG3;
+ private static final Map propsToChangeXP5;
+ private static final Map propsToChangeOP8P;
+ private static final Map propsToChangeOP9R;
+ private static final Map propsToChange11T;
+ private static final Map propsToChangeF4;
+ private static final Map> propsToKeep;
+
+ // Packages to Spoof as Pixel 7 Pro
+ private static final String[] packagesToChangePixel7Pro = {
+ "com.google.android.apps.wallpaper",
+ "com.google.android.apps.privacy.wildlife",
+ "com.google.android.apps.subscriptions.red",
+ "com.google.android.inputmethod.latin"
+ };
+
+ // Packages to Spoof as Pixel XL
+ private static final String[] packagesToChangePixelXL = {
+ "com.samsung.accessory",
+ "com.samsung.accessory.fridaymgr",
+ "com.samsung.accessory.berrymgr",
+ "com.samsung.accessory.neobeanmgr",
+ "com.samsung.android.app.watchmanager",
+ "com.samsung.android.geargplugin",
+ "com.samsung.android.gearnplugin",
+ "com.samsung.android.modenplugin",
+ "com.samsung.android.neatplugin",
+ "com.samsung.android.waterplugin"
+ };
+
+ // Packages to Spoof as Pixel 7 Pro
+ private static final String[] extraPackagesToChange = {
+ "com.android.chrome",
+ "com.android.vending",
+ "com.breel.wallpapers20",
+ "com.nhs.online.nhsonline",
+ "com.netflix.mediaclient"
+ };
+
+ // Packages to Keep with original device
+ private static final String[] packagesToKeep = {
+ "com.google.android.GoogleCamera",
+ "com.google.android.GoogleCamera.Cameight",
+ "com.google.android.GoogleCamera.Go",
+ "com.google.android.GoogleCamera.Urnyx",
+ "com.google.android.GoogleCameraAsp",
+ "com.google.android.GoogleCameraCVM",
+ "com.google.android.GoogleCameraEng",
+ "com.google.android.GoogleCameraEng2",
+ "com.google.android.GoogleCameraGood",
+ "com.google.android.MTCL83",
+ "com.google.android.UltraCVM",
+ "com.google.android.apps.cameralite",
+ "com.google.android.dialer",
+ "com.google.android.euicc",
+ "com.google.ar.core",
+ "com.google.android.youtube",
+ "com.google.android.apps.youtube.kids",
+ "com.google.android.apps.youtube.music",
+ "com.google.android.apps.recorder",
+ "com.google.android.apps.wearables.maestro.companion"
+ };
+
+ // Packages to Spoof as ROG Phone 1
+ private static final String[] packagesToChangeROG1 = {
+ "com.madfingergames.legends"
+ };
+
+ // Packages to Spoof as ROG Phone 3
+ private static final String[] packagesToChangeROG3 = {
+ "com.pearlabyss.blackdesertm",
+ "com.pearlabyss.blackdesertm.gl"
+ };
+
+ // Packages to Spoof as Xperia 5
+ private static final String[] packagesToChangeXP5 = {
+ "com.activision.callofduty.shooter",
+ "com.garena.game.codm",
+ "com.tencent.tmgp.kr.codm",
+ "com.vng.codmvn"
+ };
+
+ // Packages to Spoof as OnePlus 8 Pro
+ private static final String[] packagesToChangeOP8P = {
+ "com.netease.lztgglobal",
+ "com.pubg.imobile",
+ "com.pubg.krmobile",
+ "com.rekoo.pubgm",
+ "com.riotgames.league.wildrift",
+ "com.riotgames.league.wildrifttw",
+ "com.riotgames.league.wildriftvn",
+ "com.tencent.ig",
+ "com.tencent.tmgp.pubgmhd",
+ "com.vng.pubgmobile"
+ };
+
+ // Packages to Spoof as OnePlus 9R
+ private static final String[] packagesToChangeOP9R = {
+ "com.epicgames.fortnite",
+ "com.epicgames.portal"
+ };
+
+ // Packages to Spoof as Mi 11T
+ private static final String[] packagesToChange11T = {
+ "com.ea.gp.apexlegendsmobilefps",
+ "com.levelinfinite.hotta.gp",
+ "com.mobile.legends",
+ "com.supercell.clashofclans",
+ "com.tencent.tmgp.sgame",
+ "com.vng.mlbbvn"
+ };
+
+ // Packages to Spoof as POCO F4
+ private static final String[] packagesToChangeF4 = {
+ "com.dts.freefiremax",
+ "com.dts.freefireth"
+ };
+
+ // Codenames for currently supported Pixels by Google
+ private static final String[] pixelCodenames = {
+ "cheetah",
+ "panther",
+ "bluejay",
+ "oriole",
+ "raven",
+ "barbet",
+ "redfin",
+ "bramble",
+ "sunfish",
+ "coral",
+ "flame"
+ };
+
+ private static volatile boolean sIsGms = false;
+ private static volatile boolean sIsFinsky = false;
+
+ static {
+ propsToKeep = new HashMap<>();
+ propsToChange = new HashMap<>();
+ propsToKeep.put("com.google.android.settings.intelligence", new ArrayList<>(Collections.singletonList("FINGERPRINT")));
+ propsToChangePixel7Pro = new HashMap<>();
+ propsToChangePixel7Pro.put("BRAND", "google");
+ propsToChangePixel7Pro.put("MANUFACTURER", "Google");
+ propsToChangePixel7Pro.put("DEVICE", "cheetah");
+ propsToChangePixel7Pro.put("PRODUCT", "cheetah");
+ propsToChangePixel7Pro.put("MODEL", "Pixel 7 Pro");
+ propsToChangePixel7Pro.put("FINGERPRINT", "google/cheetah/cheetah:13/TQ1A.221205.011/9244662:user/release-keys");
+ propsToChangePixel5 = new HashMap<>();
+ propsToChangePixel5.put("BRAND", "google");
+ propsToChangePixel5.put("MANUFACTURER", "Google");
+ propsToChangePixel5.put("DEVICE", "redfin");
+ propsToChangePixel5.put("PRODUCT", "redfin");
+ propsToChangePixel5.put("MODEL", "Pixel 5");
+ propsToChangePixel5.put("FINGERPRINT", "google/redfin/redfin:13/TQ1A.221205.011/9244662:user/release-keys");
+ propsToChangePixelXL = new HashMap<>();
+ propsToChangePixelXL.put("BRAND", "google");
+ propsToChangePixelXL.put("MANUFACTURER", "Google");
+ propsToChangePixelXL.put("DEVICE", "marlin");
+ propsToChangePixelXL.put("PRODUCT", "marlin");
+ propsToChangePixelXL.put("MODEL", "Pixel XL");
+ propsToChangePixelXL.put("FINGERPRINT", "google/marlin/marlin:10/QP1A.191005.007.A3/5972272:user/release-keys");
+ propsToChangeROG1 = new HashMap<>();
+ propsToChangeROG1.put("MODEL", "ASUS_Z01QD");
+ propsToChangeROG1.put("MANUFACTURER", "asus");
+ propsToChangeROG3 = new HashMap<>();
+ propsToChangeROG3.put("MODEL", "ASUS_I003D");
+ propsToChangeROG3.put("MANUFACTURER", "asus");
+ propsToChangeXP5 = new HashMap<>();
+ propsToChangeXP5.put("MODEL", "SO-52A");
+ propsToChangeXP5.put("MANUFACTURER", "Sony");
+ propsToChangeOP8P = new HashMap<>();
+ propsToChangeOP8P.put("MODEL", "IN2020");
+ propsToChangeOP8P.put("MANUFACTURER", "OnePlus");
+ propsToChangeOP9R = new HashMap<>();
+ propsToChangeOP9R.put("MODEL", "LE2101");
+ propsToChangeOP9R.put("MANUFACTURER", "OnePlus");
+ propsToChange11T = new HashMap<>();
+ propsToChange11T.put("MODEL", "21081111RG");
+ propsToChange11T.put("MANUFACTURER", "Xiaomi");
+ propsToChangeF4 = new HashMap<>();
+ propsToChangeF4.put("MODEL", "22021211RG");
+ propsToChangeF4.put("MANUFACTURER", "Xiaomi");
+ }
+
+ public static void setProps(String packageName) {
+ if (packageName == null || packageName.isEmpty()) {
+ return;
+ }
+ if (Arrays.asList(packagesToKeep).contains(packageName)) {
+ return;
+ }
+ if (packageName.startsWith("com.google.")
+ || Arrays.asList(extraPackagesToChange).contains(packageName)) {
+
+ boolean isPixelDevice = Arrays.asList(pixelCodenames).contains(SystemProperties.get(DEVICE));
+
+ if (packageName.equals("com.google.android.apps.photos")) {
+ if (SystemProperties.getBoolean("persist.sys.pixelprops.gphotos", true)) {
+ propsToChange.putAll(propsToChangePixelXL);
+ } else {
+ if (isPixelDevice) return;
+ propsToChange.putAll(propsToChangePixel5);
+ }
+ } else if (packageName.equals("com.netflix.mediaclient") &&
+ !SystemProperties.getBoolean("persist.sys.pixelprops.netflix", false)) {
+ if (DEBUG) Log.d(TAG, "Netflix spoofing disabled by system prop");
+ return;
+ } else if (isPixelDevice) {
+ return;
+ } else if (packageName.equals("com.android.vending")) {
+ sIsFinsky = true;
+ return;
+ } else {
+ if (Arrays.asList(packagesToChangePixel7Pro).contains(packageName)) {
+ propsToChange.putAll(propsToChangePixel7Pro);
+ } else if (Arrays.asList(packagesToChangePixelXL).contains(packageName)) {
+ propsToChange.putAll(propsToChangePixelXL);
+ } else {
+ propsToChange.putAll(propsToChangePixel5);
+ }
+ }
+
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChange.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ if (propsToKeep.containsKey(packageName) && propsToKeep.get(packageName).contains(key)) {
+ if (DEBUG) Log.d(TAG, "Not defining " + key + " prop for: " + packageName);
+ continue;
+ }
+ if (DEBUG) Log.d(TAG, "Defining " + key + " prop for: " + packageName);
+ setPropValue(key, value);
+ }
+ if (packageName.equals("com.google.android.gms")) {
+ final String processName = Application.getProcessName();
+ if (processName.equals("com.google.android.gms.unstable")) {
+ sIsGms = true;
+ spoofBuildGms();
+ }
+ return;
+ }
+ // Set proper indexing fingerprint
+ if (packageName.equals("com.google.android.settings.intelligence")) {
+ setPropValue("FINGERPRINT", Build.VERSION.INCREMENTAL);
+ }
+ } else {
+
+ if (!SystemProperties.getBoolean("persist.sys.pixelprops.games", false))
+ return;
+
+ if (Arrays.asList(packagesToChangeROG1).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChangeROG1.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ } else if (Arrays.asList(packagesToChangeROG3).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChangeROG3.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ } else if (Arrays.asList(packagesToChangeXP5).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChangeXP5.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ } else if (Arrays.asList(packagesToChangeOP8P).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChangeOP8P.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ } else if (Arrays.asList(packagesToChangeOP9R).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChangeOP9R.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ } else if (Arrays.asList(packagesToChange11T).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChange11T.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ } else if (Arrays.asList(packagesToChangeF4).contains(packageName)) {
+ if (DEBUG) Log.d(TAG, "Defining props for: " + packageName);
+ for (Map.Entry prop : propsToChangeF4.entrySet()) {
+ String key = prop.getKey();
+ Object value = prop.getValue();
+ setPropValue(key, value);
+ }
+ }
+ }
+ }
+
+ private static void setPropValue(String key, Object value) {
+ try {
+ if (DEBUG) Log.d(TAG, "Defining prop " + key + " to " + value.toString());
+ Field field = Build.class.getDeclaredField(key);
+ field.setAccessible(true);
+ field.set(null, value);
+ field.setAccessible(false);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ Log.e(TAG, "Failed to set prop " + key, e);
+ }
+ }
+
+ private static void setBuildField(String key, String value) {
+ try {
+ // Unlock
+ Field field = Build.class.getDeclaredField(key);
+ field.setAccessible(true);
+
+ // Edit
+ field.set(null, value);
+
+ // Lock
+ field.setAccessible(false);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ Log.e(TAG, "Failed to spoof Build." + key, e);
+ }
+ }
+
+ private static void setVersionField(String key, Integer value) {
+ try {
+ // Unlock
+ Field field = Build.VERSION.class.getDeclaredField(key);
+ field.setAccessible(true);
+
+ // Edit
+ field.set(null, value);
+
+ // Lock
+ field.setAccessible(false);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ Log.e(TAG, "Failed to spoof Build." + key, e);
+ }
+ }
+
+ private static void spoofBuildGms() {
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
+ setBuildField("PRODUCT", "marlin");
+ setBuildField("DEVICE", "marlin");
+ setBuildField("MODEL", "Pixel XL");
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
+ }
+
+ private static boolean isCallerSafetyNet() {
+ return sIsGms && Arrays.stream(Thread.currentThread().getStackTrace())
+ .anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
+ }
+
+ public static void onEngineGetCertificateChain() {
+ // Check stack for SafetyNet or Play Integrity
+ if (isCallerSafetyNet() || sIsFinsky) {
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/core/java/com/android/internal/util/omni/OmniJawsClient.java b/core/java/com/android/internal/util/omni/OmniJawsClient.java
new file mode 100644
index 000000000000..24883093eb39
--- /dev/null
+++ b/core/java/com/android/internal/util/omni/OmniJawsClient.java
@@ -0,0 +1,560 @@
+/*
+* Copyright (C) 2017 The OmniROM 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.omni;
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+
+public class OmniJawsClient {
+ private static final String TAG = "SystemUI:OmniJawsClient";
+ private static final boolean DEBUG = false;
+ public static final String SERVICE_PACKAGE = "org.omnirom.omnijaws";
+ public static final Uri WEATHER_URI
+ = Uri.parse("content://org.omnirom.omnijaws.provider/weather");
+ public static final Uri SETTINGS_URI
+ = Uri.parse("content://org.omnirom.omnijaws.provider/settings");
+
+ private static final String ICON_PACKAGE_DEFAULT = "org.omnirom.omnijaws";
+ private static final String ICON_PREFIX_DEFAULT = "outline";
+ private static final String EXTRA_ERROR = "error";
+ public static final int EXTRA_ERROR_NETWORK = 0;
+ public static final int EXTRA_ERROR_LOCATION = 1;
+ public static final int EXTRA_ERROR_DISABLED = 2;
+
+ public static final String[] WEATHER_PROJECTION = new String[]{
+ "city",
+ "wind_speed",
+ "wind_direction",
+ "condition_code",
+ "temperature",
+ "humidity",
+ "condition",
+ "forecast_low",
+ "forecast_high",
+ "forecast_condition",
+ "forecast_condition_code",
+ "time_stamp",
+ "forecast_date",
+ "pin_wheel"
+ };
+
+ final String[] SETTINGS_PROJECTION = new String[] {
+ "enabled",
+ "units",
+ "provider",
+ "setup"
+ };
+
+ private static final String WEATHER_UPDATE = "org.omnirom.omnijaws.WEATHER_UPDATE";
+ private static final String WEATHER_ERROR = "org.omnirom.omnijaws.WEATHER_ERROR";
+
+ private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
+ private static final String WEATHER_SETTINGS = "com.android.settings.Settings$OmniJawsSettingsActivity";
+ private static final String EXTRA_SHOW_FRAGMENT = ":android:show_fragment";
+
+ private static final DecimalFormat sNoDigitsFormat = new DecimalFormat("0");
+
+ public static class WeatherInfo {
+ public String city;
+ public String windSpeed;
+ public String windDirection;
+ public int conditionCode;
+ public String temp;
+ public String humidity;
+ public String condition;
+ public Long timeStamp;
+ public List forecasts;
+ public String tempUnits;
+ public String windUnits;
+ public String provider;
+ public String pinWheel;
+
+ public String toString() {
+ return city + ":" + new Date(timeStamp) + ": " + windSpeed + ":" + windDirection + ":" +conditionCode + ":" + temp + ":" + humidity + ":" + condition + ":" + tempUnits + ":" + windUnits + ": " + forecasts;
+ }
+
+ public String getLastUpdateTime() {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+ return sdf.format(new Date(timeStamp));
+ }
+ }
+
+ public static class DayForecast {
+ public String low;
+ public String high;
+ public int conditionCode;
+ public String condition;
+ public String date;
+
+ public String toString() {
+ return "[" + low + ":" + high + ":" +conditionCode + ":" + condition + ":" + date + "]";
+ }
+ }
+
+ public static class PackageInfo {
+ public String packageName;
+ public int resourceID;
+
+ public String toString() {
+ return "[" + packageName + ":" + resourceID + "]";
+ }
+ }
+
+ public static interface OmniJawsObserver {
+ public void weatherUpdated();
+ public void weatherError(int errorReason);
+ default public void updateSettings() {};
+ }
+
+ private class WeatherUpdateReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ String action = intent.getAction();
+ for (OmniJawsObserver observer : mObserver) {
+ if (action.equals(WEATHER_UPDATE)) {
+ observer.weatherUpdated();
+ }
+ if (action.equals(WEATHER_ERROR)) {
+ int errorReason = intent.getIntExtra(EXTRA_ERROR, 0);
+ observer.weatherError(errorReason);
+ }
+ }
+ }
+ }
+
+ private class OmniJawsSettingsObserver extends ContentObserver {
+ OmniJawsSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(
+ Settings.System.OMNIJAWS_WEATHER_ICON_PACK),
+ false, this, UserHandle.USER_ALL);
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ updateSettings();
+ }
+
+ public void unregister() {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+ }
+
+ private Context mContext;
+ private WeatherInfo mCachedInfo;
+ private PackageInfo mImageInfo;
+ private Resources mRes;
+ private String mPackageName;
+ private String mIconPrefix;
+ private String mSettingIconPackage;
+ private boolean mMetric;
+ private List mObserver;
+ private WeatherUpdateReceiver mReceiver;
+ private OmniJawsSettingsObserver mSettingsObserver;
+ private Handler mHandler = new Handler();
+
+ public OmniJawsClient(Context context) {
+ mContext = context;
+ mObserver = new ArrayList();
+ mSettingsObserver = new OmniJawsSettingsObserver(mHandler);
+ mSettingsObserver.observe();
+ }
+
+ public OmniJawsClient(Context context, boolean settingsObserver) {
+ mContext = context;
+ mObserver = new ArrayList();
+ if (settingsObserver) {
+ mSettingsObserver = new OmniJawsSettingsObserver(mHandler);
+ mSettingsObserver.observe();
+ }
+ }
+
+ public void addSettingsObserver() {
+ if (mSettingsObserver == null) {
+ mSettingsObserver = new OmniJawsSettingsObserver(mHandler);
+ mSettingsObserver.observe();
+ }
+ }
+
+ public void cleanupObserver() {
+ if (mReceiver != null) {
+ try {
+ mContext.unregisterReceiver(mReceiver);
+ } catch (Exception e) {
+ }
+ mReceiver = null;
+ }
+ if (mSettingsObserver != null) {
+ mSettingsObserver.unregister();
+ }
+ }
+
+ public void updateWeather() {
+ if (isOmniJawsServiceInstalled()) {
+ Intent updateIntent = new Intent(Intent.ACTION_MAIN)
+ .setClassName(SERVICE_PACKAGE, SERVICE_PACKAGE + ".WeatherService");
+ updateIntent.setAction(SERVICE_PACKAGE + ".ACTION_UPDATE");
+ mContext.startService(updateIntent);
+ }
+ }
+
+ public Intent getSettingsIntent() {
+ if (isOmniJawsServiceInstalled()) {
+ Intent settings = new Intent(Intent.ACTION_MAIN);
+ settings.setClassName(SETTINGS_PACKAGE_NAME, WEATHER_SETTINGS);
+ settings.putExtra(EXTRA_SHOW_FRAGMENT, WEATHER_SETTINGS);
+ return settings;
+ }
+ return null;
+ }
+
+ public WeatherInfo getWeatherInfo() {
+ return mCachedInfo;
+ }
+
+ public PackageInfo getPackageInfo() {
+ return mImageInfo;
+ }
+
+ private static String getFormattedValue(float value) {
+ if (Float.isNaN(value)) {
+ return "-";
+ }
+ String formatted = sNoDigitsFormat.format(value);
+ if (formatted.equals("-0")) {
+ formatted = "0";
+ }
+ return formatted;
+ }
+
+ public void queryWeather() {
+ if (!isOmniJawsEnabled()) {
+ Log.w(TAG, "queryWeather while disabled");
+ mCachedInfo = null;
+ return;
+ }
+ Cursor c = mContext.getContentResolver().query(WEATHER_URI, WEATHER_PROJECTION,
+ null, null, null);
+ mCachedInfo = null;
+ if (c != null) {
+ try {
+ int count = c.getCount();
+ if (count > 0) {
+ mCachedInfo = new WeatherInfo();
+ List forecastList = new ArrayList();
+ int i = 0;
+ for (i = 0; i < count; i++) {
+ c.moveToPosition(i);
+ if (i == 0) {
+ mCachedInfo.city = c.getString(0);
+ mCachedInfo.windSpeed = getFormattedValue(c.getFloat(1));
+ mCachedInfo.windDirection = String.valueOf(c.getInt(2)) + "\u00b0";
+ mCachedInfo.conditionCode = c.getInt(3);
+ mCachedInfo.temp = getFormattedValue(c.getFloat(4));
+ mCachedInfo.humidity = c.getString(5);
+ mCachedInfo.condition = c.getString(6);
+ mCachedInfo.timeStamp = Long.valueOf(c.getString(11));
+ mCachedInfo.pinWheel = c.getString(13);
+ } else {
+ DayForecast day = new DayForecast();
+ day.low = getFormattedValue(c.getFloat(7));
+ day.high = getFormattedValue(c.getFloat(8));
+ day.condition = c.getString(9);
+ day.conditionCode = c.getInt(10);
+ day.date = c.getString(12);
+ forecastList.add(day);
+ }
+ }
+ mCachedInfo.forecasts = forecastList;
+ }
+ } finally {
+ c.close();
+ }
+ }
+ updateUnits();
+ if (DEBUG) Log.d(TAG, "queryWeather " + mCachedInfo);
+ }
+
+ private void loadDefaultIconsPackage() {
+ mPackageName = ICON_PACKAGE_DEFAULT;
+ mIconPrefix = ICON_PREFIX_DEFAULT;
+ mSettingIconPackage = mPackageName + "." + mIconPrefix;
+ if (DEBUG) Log.d(TAG, "Load default icon pack " + mSettingIconPackage + " " + mPackageName + " " + mIconPrefix);
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ mRes = packageManager.getResourcesForApplication(mPackageName);
+ } catch (Exception e) {
+ mRes = null;
+ }
+ if (mRes == null) {
+ Log.w(TAG, "No default package found");
+ }
+ }
+
+ private Drawable getDefaultConditionImage() {
+ String packageName = ICON_PACKAGE_DEFAULT;
+ String iconPrefix = ICON_PREFIX_DEFAULT;
+
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ Resources res = packageManager.getResourcesForApplication(packageName);
+ if (res != null) {
+ int resId = res.getIdentifier(iconPrefix + "_na", "drawable", packageName);
+ Drawable d = res.getDrawable(resId);
+ if (d != null) {
+ setWeatherConditionImageResources(resId, packageName);
+ return d;
+ }
+ }
+ } catch (Exception e) {
+ }
+ // absolute absolute fallback
+ Log.w(TAG, "No default package found");
+ return new ColorDrawable(Color.RED);
+ }
+
+ private void loadCustomIconPackage() {
+ int idx = mSettingIconPackage.lastIndexOf(".");
+ mPackageName = mSettingIconPackage.substring(0, idx);
+ mIconPrefix = mSettingIconPackage.substring(idx + 1);
+ if (DEBUG) Log.d(TAG, "Load custom icon pack " + mSettingIconPackage + " " + mPackageName + " " + mIconPrefix);
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ mRes = packageManager.getResourcesForApplication(mPackageName);
+ } catch (Exception e) {
+ mRes = null;
+ }
+ if (mRes == null) {
+ Log.w(TAG, "Icon pack loading failed - loading default");
+ loadDefaultIconsPackage();
+ }
+ }
+
+ private void setWeatherConditionImageResources(int resId, String PackageName) {
+ if (DEBUG) {
+ Log.d(TAG, "Setting mImageInfo.resourceID:" + resId);
+ Log.d(TAG, "Setting mImageInfo.packageName:" + PackageName);
+ }
+ mImageInfo.packageName = PackageName;
+ mImageInfo.resourceID = resId;
+ }
+
+ public Drawable getWeatherConditionImage(int conditionCode) {
+ /* Wrapper function allowing to load icon from default package defined as ICON_PACKAGE_DEFAULT,
+ for instance in the weather QS tile where a colored icon rendered improperly */
+
+ return getWeatherConditionImagefromPack(conditionCode, /* Don't force default pack*/ false);
+ }
+
+ public Drawable getWeatherConditionImagefromPack(int conditionCode, boolean defaultPack) {
+ if (!isOmniJawsEnabled()) {
+ Log.w(TAG, "Requesting condition image while disabled");
+ return null;
+ }
+ if (!isAvailableApp(mPackageName) || defaultPack) {
+ Log.w(TAG, "Icon pack no longer available - loading default " + mPackageName);
+ loadDefaultIconsPackage();
+ }
+ if (mRes == null) {
+ Log.w(TAG, "Requesting condition image while disabled");
+ return null;
+ }
+ try {
+ mImageInfo = new PackageInfo();
+ int resId = mRes.getIdentifier(mIconPrefix + "_" + conditionCode, "drawable", mPackageName);
+ Drawable d = mRes.getDrawable(resId);
+ if (d != null) {
+ setWeatherConditionImageResources(resId, mPackageName);
+ return d;
+ }
+ Log.w(TAG, "Failed to get condition image for " + conditionCode + " use default");
+ resId = mRes.getIdentifier(mIconPrefix + "_na", "drawable", mPackageName);
+ d = mRes.getDrawable(resId);
+ if (d != null) {
+ setWeatherConditionImageResources(resId, mPackageName);
+ return d;
+ }
+ } catch(Exception e) {
+ }
+ Log.w(TAG, "Failed to get condition image for " + conditionCode);
+ return getDefaultConditionImage();
+ }
+
+ public boolean isOmniJawsServiceInstalled() {
+ return isAvailableApp(SERVICE_PACKAGE);
+ }
+
+ public boolean isOmniJawsEnabled() {
+ if (!isOmniJawsServiceInstalled()) {
+ return false;
+ }
+ final Cursor c = mContext.getContentResolver().query(SETTINGS_URI, SETTINGS_PROJECTION,
+ null, null, null);
+ if (c != null) {
+ int count = c.getCount();
+ if (count == 1) {
+ c.moveToPosition(0);
+ boolean enabled = c.getInt(0) == 1;
+ return enabled;
+ }
+ }
+ return true;
+ }
+
+ public void setOmniJawsEnabled(boolean value) {
+ if (isOmniJawsServiceInstalled()) {
+ // check first time enablement and redirect to settings
+ // cause we need to enable gps for it
+ Intent updateIntent = new Intent(Intent.ACTION_MAIN)
+ .setClassName(SERVICE_PACKAGE, SERVICE_PACKAGE + ".WeatherService");
+ updateIntent.setAction(SERVICE_PACKAGE + ".ACTION_ENABLE");
+ updateIntent.putExtra("enable", value);
+ mContext.startService(updateIntent);
+ }
+ }
+
+ public boolean isOmniJawsSetupDone() {
+ if (!isOmniJawsServiceInstalled()) {
+ return false;
+ }
+ final Cursor c = mContext.getContentResolver().query(SETTINGS_URI, SETTINGS_PROJECTION,
+ null, null, null);
+ if (c != null) {
+ int count = c.getCount();
+ if (count == 1) {
+ c.moveToPosition(0);
+ boolean setupDone = c.getInt(3) == 1;
+ return setupDone;
+ }
+ }
+ return true;
+ }
+
+ private void updateUnits() {
+ if (!isOmniJawsServiceInstalled()) {
+ return;
+ }
+ final Cursor c = mContext.getContentResolver().query(SETTINGS_URI, SETTINGS_PROJECTION,
+ null, null, null);
+ if (c != null) {
+ int count = c.getCount();
+ if (count == 1) {
+ c.moveToPosition(0);
+ mMetric = c.getInt(1) == 0;
+ if (mCachedInfo != null) {
+ mCachedInfo.tempUnits = getTemperatureUnit();
+ mCachedInfo.windUnits = getWindUnit();
+ mCachedInfo.provider = c.getString(2);
+ }
+ }
+ }
+ }
+
+ private String getTemperatureUnit() {
+ return "\u00b0" + (mMetric ? "C" : "F");
+ }
+
+ private String getWindUnit() {
+ return mMetric ? "km/h":"mph";
+ }
+
+ private void updateSettings() {
+ if (isOmniJawsServiceInstalled()) {
+ final String iconPack = Settings.System.getStringForUser(mContext.getContentResolver(),
+ Settings.System.OMNIJAWS_WEATHER_ICON_PACK, UserHandle.USER_CURRENT);
+ if (iconPack == null) {
+ loadDefaultIconsPackage();
+ } else if (mSettingIconPackage == null || !iconPack.equals(mSettingIconPackage)) {
+ mSettingIconPackage = iconPack;
+ loadCustomIconPackage();
+ }
+ for (OmniJawsObserver observer : mObserver) {
+ observer.updateSettings();
+ }
+ }
+ }
+
+ private boolean isAvailableApp(String packageName) {
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
+ int enabled = pm.getApplicationEnabledSetting(packageName);
+ return enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED &&
+ enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ public void addObserver(OmniJawsObserver observer) {
+ if (mObserver.size() == 0) {
+ if (mReceiver != null) {
+ try {
+ mContext.unregisterReceiver(mReceiver);
+ } catch (Exception e) {
+ }
+ }
+ mReceiver = new WeatherUpdateReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(WEATHER_UPDATE);
+ filter.addAction(WEATHER_ERROR);
+ mContext.registerReceiver(mReceiver, filter);
+ }
+ mObserver.add(observer);
+ }
+
+ public void removeObserver(OmniJawsObserver observer) {
+ mObserver.remove(observer);
+ if (mObserver.size() == 0 && mReceiver != null) {
+ try {
+ mContext.unregisterReceiver(mReceiver);
+ } catch (Exception e) {
+ }
+ mReceiver = null;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/view/BaseSurfaceHolder.java b/core/java/com/android/internal/view/BaseSurfaceHolder.java
index 32ce0fe1282b..1ae1307633bb 100644
--- a/core/java/com/android/internal/view/BaseSurfaceHolder.java
+++ b/core/java/com/android/internal/view/BaseSurfaceHolder.java
@@ -241,4 +241,4 @@ public void setSurfaceFrameSize(int width, int height) {
mSurfaceFrame.right = width;
mSurfaceFrame.bottom = height;
}
-};
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index a4da8de44880..73af16c250cc 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -80,6 +80,11 @@ public class LockPatternUtils {
*/
public static final String LEGACY_LOCK_PATTERN_ENABLED = "legacy_lock_pattern_enabled";
+ /**
+ * The key to store PIN/Password length for quick unlock.
+ **/
+ public static final String KEY_PIN_PASSWORD_LENGTH = "pin_password_length";
+
/**
* The interval of the countdown for showing progress of the lockout.
*/
@@ -1522,8 +1527,7 @@ public static class StrongAuthTracker {
STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
STRONG_AUTH_REQUIRED_AFTER_TIMEOUT,
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
- STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT,
- SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED})
+ STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT})
@Retention(RetentionPolicy.SOURCE)
public @interface StrongAuthFlags {}
@@ -1575,12 +1579,6 @@ public static class StrongAuthTracker {
*/
public static final int STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT = 0x80;
- /**
- * Some authentication is required because the trustagent either timed out or was disabled
- * manually.
- */
- public static final int SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED = 0x100;
-
/**
* Strong auth flags that do not prevent biometric methods from being accepted as auth.
* If any other flags are set, biometric authentication is disabled.
@@ -1812,4 +1810,23 @@ public void removeCachedUnifiedChallenge(int userId) {
re.rethrowFromSystemServer();
}
}
+
+ public int getPinPasswordLength(int userId) {
+ int mPinPasswordLength = -1;
+ try {
+ mPinPasswordLength = (int) getLockSettings().getLong(KEY_PIN_PASSWORD_LENGTH, -1,
+ userId);
+ } catch (Exception e) {
+ Log.d("getPinPasswordLength", "getLong error: " + e.getMessage());
+ }
+ return mPinPasswordLength;
+ }
+
+ public void setPinPasswordLength(int length, int userId) {
+ try {
+ getLockSettings().setLong(KEY_PIN_PASSWORD_LENGTH, (long) length, userId);
+ } catch (Exception e) {
+ Log.d("savePinPasswordLength", "saveLong error: " + e.getMessage());
+ }
+ }
}
diff --git a/core/java/com/android/server/LocalServices.java b/core/java/com/android/server/LocalServices.java
index 9c632ea725a9..ca94bb08afc0 100644
--- a/core/java/com/android/server/LocalServices.java
+++ b/core/java/com/android/server/LocalServices.java
@@ -18,7 +18,7 @@
import com.android.internal.annotations.VisibleForTesting;
-import android.util.ArrayMap;
+import java.util.HashMap;
/**
* This class is used in a similar way as ServiceManager, except the services registered here
@@ -32,8 +32,8 @@
public final class LocalServices {
private LocalServices() {}
- private static final ArrayMap, Object> sLocalServiceObjects =
- new ArrayMap, Object>();
+ private static final HashMap, Object> sLocalServiceObjects =
+ new HashMap, Object>();
/**
* Returns a local service instance that implements the specified interface.
diff --git a/core/java/ink/kaleidoscope/IParallelSpaceManager.aidl b/core/java/ink/kaleidoscope/IParallelSpaceManager.aidl
new file mode 100644
index 000000000000..ae3d8fdaf3c2
--- /dev/null
+++ b/core/java/ink/kaleidoscope/IParallelSpaceManager.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 Project Kaleidoscope
+ *
+ * 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 ink.kaleidoscope;
+
+import android.content.pm.UserInfo;
+
+/** @hide */
+interface IParallelSpaceManager {
+ int create(String name, boolean shareMedia);
+ int remove(int userId);
+ UserInfo[] getUsers();
+ UserInfo getOwner();
+ int duplicatePackage(String packageName, int userId);
+ int removePackage(String packageName, int userId);
+}
diff --git a/core/java/ink/kaleidoscope/ParallelSpaceManager.java b/core/java/ink/kaleidoscope/ParallelSpaceManager.java
new file mode 100644
index 000000000000..41938b2550c9
--- /dev/null
+++ b/core/java/ink/kaleidoscope/ParallelSpaceManager.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2022 Project Kaleidoscope
+ *
+ * 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 ink.kaleidoscope;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import ink.kaleidoscope.IParallelSpaceManager;
+
+/**
+ * Simple wrapper for ParallelSpaceManagerService.
+ * It requires android.permission.MANAGE_PARALLEL_SPACES.
+ * @hide
+ */
+public final class ParallelSpaceManager {
+
+ public static final String SERVICE_NAME = "parallel";
+ private static final String TAG = "ParallelSpaceManager";
+
+ private static ParallelSpaceManager sParallelSpaceManager;
+ private IParallelSpaceManager mParallelSpaceManager;
+
+ private ParallelSpaceManager() {
+ mParallelSpaceManager = IParallelSpaceManager.Stub.asInterface(
+ ServiceManager.getService(SERVICE_NAME));
+ if (mParallelSpaceManager == null)
+ throw new RuntimeException("Unable to get ParallelSpaceManagerService.");
+ }
+
+ public static ParallelSpaceManager getInstance() {
+ if (sParallelSpaceManager != null)
+ return sParallelSpaceManager;
+ sParallelSpaceManager = new ParallelSpaceManager();
+ return sParallelSpaceManager;
+ }
+
+ private int create(String name, boolean shareMedia) {
+ try {
+ return mParallelSpaceManager.create(name, shareMedia);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed when create(): " + e);
+ }
+ }
+
+ /**
+ * Create a parallel space. Returns user id on success, -1 otherwise.
+ */
+ public int create(String name) {
+ return create(name, false);
+ }
+
+ /**
+ * Remove a parallel space. Returns 0 on success.
+ */
+ public int remove(int userId) {
+ try {
+ return mParallelSpaceManager.remove(userId);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed when remove(): " + e);
+ }
+ }
+
+ /**
+ * Get a UserInfo list of current existing parallel users.
+ */
+ public List getParallelUsers() {
+ try {
+ return new ArrayList<>(Arrays.asList(mParallelSpaceManager.getUsers()));
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed when getUsers(): " + e);
+ }
+ }
+
+ /**
+ * Get a user id list of current existing parallel users.
+ */
+ public List getParallelUserIds() {
+ ArrayList ret = new ArrayList<>();
+ getParallelUsers().forEach(user -> ret.add(user.id));
+ return ret;
+ }
+
+ /**
+ * Get a UserHandle list of current existing parallel users.
+ */
+ public List getParallelUserHandles() {
+ ArrayList ret = new ArrayList<>();
+ getParallelUserIds().forEach(id -> ret.add(UserHandle.of(id)));
+ return ret;
+ }
+
+ /**
+ * Get UserInfo of currently foreground parallel space owner.
+ */
+ public UserInfo getParallelOwner() {
+ try {
+ return mParallelSpaceManager.getOwner();
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed when getParallelOwner(): " + e);
+ }
+ }
+
+ /**
+ * Get user id of currently foreground parallel space owner.
+ */
+ public int getParallelOwnerId() {
+ UserInfo owner = getParallelOwner();
+ return owner != null ? owner.id : 0;
+ }
+
+ /**
+ * Get UserHandle of currently foreground parallel space owner.
+ */
+ public UserHandle getParallelOwnerHandle() {
+ return UserHandle.of(getParallelOwnerId());
+ }
+
+ /**
+ * Install an existing package to target user. Returns 0 on success.
+ */
+ public int duplicatePackage(String packageName, int userId) {
+ try {
+ return mParallelSpaceManager.duplicatePackage(packageName, userId);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed when duplicatePackage(): " + e);
+ }
+ }
+
+ /**
+ * Remove a package from target user. Returns 0 on success.
+ */
+ public int removePackage(String packageName, int userId) {
+ try {
+ return mParallelSpaceManager.removePackage(packageName, userId);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed when removePackage(): " + e);
+ }
+ }
+}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index aa661713b1fe..47d989be004a 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -50,6 +50,7 @@ cc_library_shared {
"android_util_XmlBlock.cpp",
"android_util_jar_StrictJarFile.cpp",
"com_android_internal_util_VirtualRefBasePtr.cpp",
+ "com_android_internal_app_ActivityTrigger.cpp",
":deviceproductinfoconstants_aidl",
],
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index eba6cca76389..351ac91d3fd1 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -211,6 +211,7 @@ extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
extern int register_android_window_WindowInfosListener(JNIEnv* env);
+extern int register_com_android_internal_app_ActivityTrigger(JNIEnv *env);
// Namespace for Android Runtime flags applied during boot time.
static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
@@ -1651,6 +1652,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_android_security_Scrypt),
+ REG_JNI(register_com_android_internal_app_ActivityTrigger),
REG_JNI(register_com_android_internal_content_F2fsUtils),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
REG_JNI(register_com_android_internal_os_FuseAppLoop),
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 365a18d174c9..7000d9803060 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -470,6 +470,56 @@ void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualM
}
}
+static void android_hardware_Camera_setLongshot(JNIEnv *env, jobject thiz, jboolean enable)
+{
+ ALOGV("setLongshot");
+ 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");
+ }
+}
+
+static void android_hardware_Camera_sendHistogramData(JNIEnv *env, jobject thiz)
+ {
+ ALOGV("sendHistogramData" );
+ 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");
+ }
+ }
+ static void android_hardware_Camera_setHistogramMode(JNIEnv *env, jobject thiz, jboolean mode)
+ {
+ ALOGV("setHistogramMode: 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_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");
+ }
+ }
void JNICameraContext::addCallbackBuffer(
JNIEnv *env, jbyteArray cbb, int msgType)
{
@@ -783,7 +833,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));
@@ -1051,7 +1119,7 @@ static int32_t android_hardware_Camera_getAudioRestriction(
//-------------------------------------------------
static const JNINativeMethod camMethods[] = {
- { "getNumberOfCameras",
+ { "_getNumberOfCameras",
"()I",
(void *)android_hardware_Camera_getNumberOfCameras },
{ "_getCameraInfo",
@@ -1096,6 +1164,18 @@ 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_setParameters",
"(Ljava/lang/String;)V",
(void *)android_hardware_Camera_setParameters },
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index 0e6b587db945..6a8c5f743840 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -48,6 +48,13 @@
#define ENCODING_DTS_UHD 27
#define ENCODING_DRA 28
+#define ENCODING_AMR_NB 100
+#define ENCODING_AMR_WB 101
+#define ENCODING_EVRC 102
+#define ENCODING_EVRC_B 103
+#define ENCODING_EVRC_WB 104
+#define ENCODING_EVRC_NW 105
+
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1
@@ -94,6 +101,18 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
return AUDIO_FORMAT_AC4;
case ENCODING_E_AC3_JOC:
return AUDIO_FORMAT_E_AC3_JOC;
+ case ENCODING_AMR_NB:
+ return AUDIO_FORMAT_AMR_NB;
+ case ENCODING_AMR_WB:
+ return AUDIO_FORMAT_AMR_WB;
+ case ENCODING_EVRC:
+ return AUDIO_FORMAT_EVRC;
+ case ENCODING_EVRC_B:
+ return AUDIO_FORMAT_EVRCB;
+ case ENCODING_EVRC_WB:
+ return AUDIO_FORMAT_EVRCWB;
+ case ENCODING_EVRC_NW:
+ return AUDIO_FORMAT_EVRCNW;
case ENCODING_DEFAULT:
return AUDIO_FORMAT_DEFAULT;
case ENCODING_DOLBY_MAT:
@@ -189,6 +208,18 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
return ENCODING_DTS_UHD;
case AUDIO_FORMAT_DRA:
return ENCODING_DRA;
+ case AUDIO_FORMAT_AMR_NB:
+ return ENCODING_AMR_NB;
+ case AUDIO_FORMAT_AMR_WB:
+ return ENCODING_AMR_WB;
+ case AUDIO_FORMAT_EVRC:
+ return ENCODING_EVRC;
+ case AUDIO_FORMAT_EVRCB:
+ return ENCODING_EVRC_B;
+ case AUDIO_FORMAT_EVRCWB:
+ return ENCODING_EVRC_WB;
+ case AUDIO_FORMAT_EVRCNW:
+ return ENCODING_EVRC_NW;
case AUDIO_FORMAT_DEFAULT:
return ENCODING_DEFAULT;
default:
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 88aa4de0db24..e9d78e12b360 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -37,6 +37,7 @@
#include
#include
+#include
#include "android_media_AudioAttributes.h"
#include "android_media_AudioDescriptor.h"
#include "android_media_AudioDeviceAttributes.h"
@@ -193,6 +194,9 @@ static struct {
static jclass gAudioDescriptorClass;
static jmethodID gAudioDescriptorCstor;
+static jclass gAppVolumeClass;
+static jmethodID gAppVolumeCstor;
+
//
// JNI Initialization for OpenSLES routing
//
@@ -843,6 +847,89 @@ android_media_AudioSystem_getMasterBalance(JNIEnv *env, jobject thiz)
return balance;
}
+
+static jint
+android_media_AudioSystem_setAppVolume(JNIEnv *env, jobject thiz, jstring packageName, jfloat value)
+{
+ const jchar* c_packageName = env->GetStringCritical(packageName, 0);
+ String8 package8 = String8(reinterpret_cast(c_packageName), env->GetStringLength(packageName));
+ env->ReleaseStringCritical(packageName, c_packageName);
+ return (jint) check_AudioSystem_Command(AudioSystem::setAppVolume(package8, value));
+}
+
+static jint
+android_media_AudioSystem_setAppMute(JNIEnv *env, jobject thiz, jstring packageName, jboolean mute)
+{
+ const jchar* c_packageName = env->GetStringCritical(packageName, 0);
+ String8 package8 = String8(reinterpret_cast(c_packageName), env->GetStringLength(packageName));
+ env->ReleaseStringCritical(packageName, c_packageName);
+ return (jint) check_AudioSystem_Command(AudioSystem::setAppMute(package8, mute));
+}
+
+jint convertAppVolumeFromNative(JNIEnv *env, jobject *jAppVolume, const media::AppVolume *AppVolume)
+{
+ jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
+ jstring jPackageName;
+ jfloat jVolume;
+ jboolean jMute;
+ jboolean jActive;
+
+ if (AppVolume == NULL || jAppVolume == NULL) {
+ jStatus = (jint)AUDIO_JAVA_ERROR;
+ goto exit;
+ }
+
+ jPackageName = env->NewStringUTF(AppVolume->packageName);
+ jVolume = AppVolume->volume;
+ jMute = AppVolume->muted;
+ jActive = AppVolume->active;
+
+ *jAppVolume = env->NewObject(gAppVolumeClass, gAppVolumeCstor,
+ jPackageName, jMute, jVolume, jActive);
+
+ env->DeleteLocalRef(jPackageName);
+exit:
+ return jStatus;
+}
+
+static jint
+android_media_AudioSystem_listAppVolumes(JNIEnv *env, jobject clazz, jobject jVolumes)
+{
+ ALOGV("listAppVolumes");
+
+ if (jVolumes == NULL) {
+ ALOGE("listAppVolumes NULL AppVolume ArrayList");
+ return (jint)AUDIO_JAVA_BAD_VALUE;
+ }
+ if (!env->IsInstanceOf(jVolumes, gArrayListClass)) {
+ ALOGE("listAppVolumes not an arraylist");
+ return (jint)AUDIO_JAVA_BAD_VALUE;
+ }
+
+ std::vector volumes;
+
+ jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
+ status_t status = AudioSystem::listAppVolumes(&volumes);
+
+ if (status != NO_ERROR) {
+ ALOGE("AudioSystem::listAppVolumes error %d", status);
+ jStatus = nativeToJavaStatus(status);
+ return jStatus;
+ }
+
+ for (size_t i = 0; i < volumes.size(); i++) {
+ jobject jAppVolume;
+ jStatus = convertAppVolumeFromNative(env, &jAppVolume, &volumes[i]);
+ if (jStatus != AUDIO_JAVA_SUCCESS) {
+ return jStatus;
+ }
+ env->CallBooleanMethod(jVolumes, gArrayListMethods.add, jAppVolume);
+ env->DeleteLocalRef(jAppVolume);
+ }
+
+ return jStatus;
+}
+
static jint
android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
{
@@ -3104,7 +3191,13 @@ static const JNINativeMethod gMethods[] =
(void *)android_media_AudioSystem_getDirectPlaybackSupport},
{"getDirectProfilesForAttributes",
"(Landroid/media/AudioAttributes;Ljava/util/ArrayList;)I",
- (void *)android_media_AudioSystem_getDirectProfilesForAttributes}};
+ (void *)android_media_AudioSystem_getDirectProfilesForAttributes},
+ {"setAppVolume", "(Ljava/lang/String;F)I",
+ (void *)android_media_AudioSystem_setAppVolume},
+ {"setAppMute", "(Ljava/lang/String;Z)I",
+ (void *)android_media_AudioSystem_setAppMute},
+ {"listAppVolumes", "(Ljava/util/ArrayList;)I",
+ (void *)android_media_AudioSystem_listAppVolumes}};
static const JNINativeMethod gEventHandlerMethods[] = {
{"native_setup",
@@ -3343,6 +3436,11 @@ int register_android_media_AudioSystem(JNIEnv *env)
gVibratorMethods.getMaxAmplitude =
GetMethodIDOrDie(env, vibratorClass, "getHapticChannelMaximumAmplitude", "()F");
+ jclass AppVolumeClass = FindClassOrDie(env, "android/media/AppVolume");
+ gAppVolumeClass = MakeGlobalRefOrDie(env, AppVolumeClass);
+ gAppVolumeCstor = GetMethodIDOrDie(env, AppVolumeClass, "",
+ "(Ljava/lang/String;ZFZ)V");
+
AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback);
RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 0a5e78617568..2e9aa3405dac 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -68,16 +68,16 @@ static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject claz
*/
static const JNINativeMethod gRegisterMethods[] = {
/* name, signature, funcPtr */
- { "writeEvent", "(II)I", (void*) ELog::writeEventInteger },
- { "writeEvent", "(IJ)I", (void*) ELog::writeEventLong },
- { "writeEvent", "(IF)I", (void*) ELog::writeEventFloat },
- { "writeEvent", "(ILjava/lang/String;)I", (void*) ELog::writeEventString },
- { "writeEvent", "(I[Ljava/lang/Object;)I", (void*) ELog::writeEventArray },
- { "readEvents",
+ { "nativeWriteEvent", "(II)I", (void*) ELog::writeEventInteger },
+ { "nativeWriteEvent", "(IJ)I", (void*) ELog::writeEventLong },
+ { "nativeWriteEvent", "(IF)I", (void*) ELog::writeEventFloat },
+ { "nativeWriteEvent", "(ILjava/lang/String;)I", (void*) ELog::writeEventString },
+ { "nativeWriteEvent", "(I[Ljava/lang/Object;)I", (void*) ELog::writeEventArray },
+ { "nativeReadEvents",
"([ILjava/util/Collection;)V",
(void*) android_util_EventLog_readEvents
},
- { "readEventsOnWrapping",
+ { "nativeReadEventsOnWrapping",
"([IJLjava/util/Collection;)V",
(void*) android_util_EventLog_readEventsOnWrapping
},
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index b9d5ee4b3015..4f19cdade122 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -279,6 +279,81 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
signalExceptionForGroupError(env, errno ? errno : EPERM, pid);
}
+void android_os_Process_setCgroupProcsProcessGroup(JNIEnv* env, jobject clazz, int uid, int pid, jint grp, jboolean dex2oat_only)
+{
+ int fd;
+ char pathV1[255], pathV2[255];
+ static bool isCgroupV2 = false;
+ if ((grp == SP_FOREGROUND) || (grp > SP_MAX)) {
+ signalExceptionForGroupError(env, EINVAL, pid);
+ return;
+ }
+
+ //set process group for current process
+ android_os_Process_setProcessGroup(env, clazz, pid, grp);
+
+ //find processes in the same cgroup.procs of current uid and pid
+ snprintf(pathV1, sizeof(pathV1), "/acct/uid_%d/pid_%d/cgroup.procs", uid, pid);
+ snprintf(pathV2, sizeof(pathV2), "/sys/fs/cgroup/uid_%d/pid_%d/cgroup.procs", uid, pid);
+ if (isCgroupV2) {
+ // read from V2 only
+ fd = open(pathV2, O_RDONLY);
+ } else {
+ // first try V1
+ fd = open(pathV1, O_RDONLY);
+ if (fd < 0) {
+ fd = open(pathV2, O_RDONLY);
+ if (fd >= 0) {
+ isCgroupV2 = true;
+ }
+ }
+ }
+ if (fd >= 0) {
+ char buffer[256];
+ char ch;
+ int numRead;
+ size_t len=0;
+ for (;;) {
+ numRead=read(fd, &ch, 1);
+ if (numRead <= 0)
+ break;
+ if (ch != '\n') {
+ buffer[len++] = ch;
+ } else {
+ int temp_pid = atoi(buffer);
+ len=0;
+ if (temp_pid == pid)
+ continue;
+ if (dex2oat_only) {
+ // check if cmdline of temp_pid is dex2oat
+ char cmdline[64];
+ snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", temp_pid);
+ int cmdline_fd = open(cmdline, O_RDONLY);
+ if (cmdline_fd >= 0) {
+ size_t read_size = read(cmdline_fd, buffer, 255);
+ close(cmdline_fd);
+ buffer[read_size]='\0';
+ const char *dex2oat_name1 = "dex2oat"; //for plugins compiler
+ const char *dex2oat_name2 = "/system/bin/dex2oat"; //for installer
+ const char *dex2oat_name3 = "/apex/com.android.runtime/bin/dex2oat"; //for installer
+ if (strncmp(buffer, dex2oat_name1, strlen(dex2oat_name1)) != 0
+ && strncmp(buffer, dex2oat_name2, strlen(dex2oat_name2)) != 0
+ && strncmp(buffer, dex2oat_name3, strlen(dex2oat_name3)) != 0) {
+ continue;
+ }
+ } else {
+ //ALOGE("read %s failed", cmdline);
+ continue;
+ }
+ }
+ //set cgroup of temp_pid follow pid
+ android_os_Process_setProcessGroup(env, clazz, temp_pid, grp);
+ }
+ }
+ close(fd);
+ }
+}
+
void android_os_Process_setProcessFrozen(
JNIEnv *env, jobject clazz, jint pid, jint uid, jboolean freeze)
{
@@ -356,8 +431,21 @@ static void get_cpuset_cores_for_policy(SchedPolicy policy, cpu_set_t *cpu_set)
}
break;
case SP_FOREGROUND:
+ if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
+ return;
+ }
+ break;
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
+ if (!CgroupGetAttributePath("AudioAppCapacityCPUs", &filename)) {
+ return;
+ }
+ if (access(filename.c_str(), F_OK) != 0) {
+ if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
+ return;
+ }
+ }
+ break;
case SP_RT_APP:
if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {
return;
@@ -1263,6 +1351,7 @@ static const JNINativeMethod methods[] = {
{"getThreadScheduler", "(I)I", (void*)android_os_Process_getThreadScheduler},
{"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup},
{"setThreadGroupAndCpuset", "(II)V", (void*)android_os_Process_setThreadGroupAndCpuset},
+ {"setCgroupProcsProcessGroup", "(IIIZ)V", (void*)android_os_Process_setCgroupProcsProcessGroup},
{"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup},
{"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup},
{"createProcessGroup", "(II)I", (void*)android_os_Process_createProcessGroup},
diff --git a/core/jni/com_android_internal_app_ActivityTrigger.cpp b/core/jni/com_android_internal_app_ActivityTrigger.cpp
new file mode 100644
index 000000000000..9d22f69d91ea
--- /dev/null
+++ b/core/jni/com_android_internal_app_ActivityTrigger.cpp
@@ -0,0 +1,256 @@
+/* Copyright (c) 2015-2017, 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.
+ *
+ */
+
+#define LOG_TAG "ActTriggerJNI"
+
+#include "jni.h"
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+namespace android
+{
+
+// ----------------------------------------------------------------------------
+/*
+ * Stuct containing handle to dynamically loaded lib as well as function
+ * pointers to key interfaces.
+ */
+typedef struct dlLibHandler {
+ void *dlhandle;
+ void (*startActivity)(const char *, int *);
+ void (*startApp)(const char *, int *);
+ void (*resumeActivity)(const char *);
+ void (*pauseActivity)(const char *);
+ void (*stopActivity)(const char *);
+ void (*init)(void);
+ void (*deinit)(void);
+ void (*miscActivity)(int, const char *, int, int, float *);
+ const char *dlname;
+}dlLibHandler;
+
+/*
+ * Init for activity trigger library
+ */
+static dlLibHandler mDlLibHandler = {
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "libqti-at.so"
+};
+
+// ----------------------------------------------------------------------------
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_init()
+{
+ bool errored = false;
+
+ mDlLibHandler.dlhandle = dlopen(mDlLibHandler.dlname, RTLD_NOW | RTLD_LOCAL);
+ if (mDlLibHandler.dlhandle == NULL) {
+ return;
+ }
+
+ *(void **) (&mDlLibHandler.startActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_start");
+ if (mDlLibHandler.startActivity == NULL) {
+ errored = true;
+ }
+
+ *(void **) (&mDlLibHandler.startApp) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_qspm_start");
+
+ if (!errored) {
+ *(void **) (&mDlLibHandler.resumeActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_resume");
+ if (mDlLibHandler.resumeActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.pauseActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_pause");
+ if (mDlLibHandler.pauseActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.stopActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_stop");
+ if (mDlLibHandler.stopActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.init) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_init");
+ if (mDlLibHandler.init == NULL) {
+ errored = true;
+ }
+ }
+ if (!errored) {
+ *(void **) (&mDlLibHandler.miscActivity) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_misc");
+ if (mDlLibHandler.miscActivity == NULL) {
+ errored = true;
+ }
+ }
+ if (errored) {
+ mDlLibHandler.startActivity = NULL;
+ mDlLibHandler.startApp = NULL;
+ mDlLibHandler.resumeActivity = NULL;
+ mDlLibHandler.pauseActivity = NULL;
+ mDlLibHandler.stopActivity = NULL;
+ mDlLibHandler.miscActivity = NULL;
+ if (mDlLibHandler.dlhandle) {
+ dlclose(mDlLibHandler.dlhandle);
+ mDlLibHandler.dlhandle = NULL;
+ }
+ } else {
+ (*mDlLibHandler.init)();
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_deinit(JNIEnv *env, jobject clazz)
+{
+ if (mDlLibHandler.dlhandle) {
+ mDlLibHandler.startActivity = NULL;
+ mDlLibHandler.startApp = NULL;
+ mDlLibHandler.resumeActivity = NULL;
+ mDlLibHandler.pauseActivity = NULL;
+ mDlLibHandler.stopActivity = NULL;
+ mDlLibHandler.miscActivity = NULL;
+
+ *(void **) (&mDlLibHandler.deinit) = dlsym(mDlLibHandler.dlhandle, "activity_trigger_deinit");
+ if (mDlLibHandler.deinit) {
+ (*mDlLibHandler.deinit)();
+ }
+
+ dlclose(mDlLibHandler.dlhandle);
+ mDlLibHandler.dlhandle = NULL;
+ }
+}
+
+static jint
+com_android_internal_app_ActivityTrigger_native_at_startActivity(JNIEnv *env, jobject clazz, jstring activity, jint flags)
+{
+ int activiyFlags = flags;
+ if(mDlLibHandler.startActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.startActivity)(actStr, &activiyFlags);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+ return activiyFlags;
+}
+
+static jint
+com_android_internal_app_ActivityTrigger_native_at_startApp(JNIEnv *env, jobject clazz, jstring activity, jint flags)
+{
+ int activiyFlags = flags;
+ if(mDlLibHandler.startApp && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.startApp)(actStr, &activiyFlags);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+ return activiyFlags;
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_resumeActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if(mDlLibHandler.resumeActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.resumeActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_pauseActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if(mDlLibHandler.pauseActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (NULL != actStr) {
+ (*mDlLibHandler.pauseActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_stopActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if(mDlLibHandler.stopActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (NULL != actStr) {
+ (*mDlLibHandler.stopActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static jfloat
+com_android_internal_app_ActivityTrigger_native_at_miscActivity(JNIEnv *env, jobject clazz, jint func, jstring activity, jint type, jint flag)
+{
+ float scaleValue = -1.0f;
+ if (mDlLibHandler.miscActivity && activity && func) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*mDlLibHandler.miscActivity)(func, actStr, type, flag, &scaleValue);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+ return scaleValue;
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"native_at_startActivity", "(Ljava/lang/String;I)I", (void *)com_android_internal_app_ActivityTrigger_native_at_startActivity},
+ {"native_at_startApp", "(Ljava/lang/String;I)I", (void *)com_android_internal_app_ActivityTrigger_native_at_startApp},
+ {"native_at_resumeActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_resumeActivity},
+ {"native_at_pauseActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_pauseActivity},
+ {"native_at_stopActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_stopActivity},
+ {"native_at_deinit", "()V", (void *)com_android_internal_app_ActivityTrigger_native_at_deinit},
+ {"native_at_miscActivity", "(ILjava/lang/String;II)F", (void *)com_android_internal_app_ActivityTrigger_native_at_miscActivity},
+};
+
+int register_com_android_internal_app_ActivityTrigger(JNIEnv *env)
+{
+ com_android_internal_app_ActivityTrigger_native_at_init();
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "com/android/internal/app/ActivityTrigger", gMethods, NELEM(gMethods));
+}
+
+} // namespace android
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 21bbac0b0a7d..c56a5fe42c91 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -128,8 +128,6 @@ static jclass gZygoteInitClass;
static jmethodID gGetOrCreateSystemServerClassLoader;
static jmethodID gPrefetchStandaloneSystemServerJars;
-static bool gIsSecurityEnforced = true;
-
/**
* True if the app process is running in its mount namespace.
*/
@@ -634,11 +632,6 @@ static void PreApplicationInit() {
}
static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
- if (!gIsSecurityEnforced) {
- ALOGI("seccomp disabled by setenforce 0");
- return;
- }
-
// Apply system or app filter based on uid.
if (uid >= AID_APP_START) {
if (is_child_zygote) {
@@ -2317,11 +2310,6 @@ static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
static void com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter(
JNIEnv* env, jclass, jint uidGidMin, jint uidGidMax) {
- if (!gIsSecurityEnforced) {
- ALOGI("seccomp disabled by setenforce 0");
- return;
- }
-
bool installed = install_setuidgid_seccomp_filter(uidGidMin, uidGidMax);
if (!installed) {
RuntimeAbort(env, __LINE__, "Could not install setuid/setgid seccomp filter.");
@@ -2398,10 +2386,6 @@ static void com_android_internal_os_Zygote_nativeInitNativeState(JNIEnv* env, jc
* Security Initialization
*/
- // security_getenforce is not allowed on app process. Initialize and cache
- // the value before zygote forks.
- gIsSecurityEnforced = security_getenforce();
-
selinux_android_seapp_context_init();
/*
diff --git a/core/proto/android/os/processstarttime.proto b/core/proto/android/os/processstarttime.proto
deleted file mode 100644
index d0f8baee7da2..000000000000
--- a/core/proto/android/os/processstarttime.proto
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2022 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.
- */
-
-syntax = "proto2";
-package android.os;
-
-option java_multiple_files = true;
-
-// This message is used for statsd logging and should be kept in sync with
-// frameworks/proto_logging/stats/atoms.proto
-/**
- * Logs information about process start time.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message ProcessStartTime {
- // The uid of the ProcessRecord.
- optional int32 uid = 1;
-
- // The process pid.
- optional int32 pid = 2;
-
- // The process name.
- // Usually package name, "system" for system server.
- // Provided by ActivityManagerService.
- optional string process_name = 3;
-
- enum StartType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
-
- // The start type.
- optional StartType type = 4;
-
- // The elapsed realtime at the start of the process.
- optional int64 process_start_time_millis = 5;
-
- // Number of milliseconds it takes to reach bind application.
- optional int32 bind_application_delay_millis = 6;
-
- // Number of milliseconds it takes to finish start of the process.
- optional int32 process_start_delay_millis = 7;
-
- // hostingType field in ProcessRecord, the component type such as "activity",
- // "service", "content provider", "broadcast" or other strings.
- optional string hosting_type = 8;
-
- // hostingNameStr field in ProcessRecord. The component class name that runs
- // in this process.
- optional string hosting_name = 9;
-
- // Broadcast action name.
- optional string broadcast_action_name = 10;
-
- enum HostingTypeId {
- HOSTING_TYPE_UNKNOWN = 0;
- HOSTING_TYPE_ACTIVITY = 1;
- HOSTING_TYPE_ADDED_APPLICATION = 2;
- HOSTING_TYPE_BACKUP = 3;
- HOSTING_TYPE_BROADCAST = 4;
- HOSTING_TYPE_CONTENT_PROVIDER = 5;
- HOSTING_TYPE_LINK_FAIL = 6;
- HOSTING_TYPE_ON_HOLD = 7;
- HOSTING_TYPE_NEXT_ACTIVITY = 8;
- HOSTING_TYPE_NEXT_TOP_ACTIVITY = 9;
- HOSTING_TYPE_RESTART = 10;
- HOSTING_TYPE_SERVICE = 11;
- HOSTING_TYPE_SYSTEM = 12;
- HOSTING_TYPE_TOP_ACTIVITY = 13;
- HOSTING_TYPE_EMPTY = 14;
- }
-
- optional HostingTypeId hosting_type_id = 11;
-}
-
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5ae133bbe6e6..ccc011e2d9da 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -816,6 +816,10 @@
+
+
+
+
@@ -3006,6 +3010,10 @@
+
+
+
+
+
+
+
+
@@ -5292,6 +5315,11 @@
+
+
+
@@ -6525,6 +6553,11 @@
+
+
+
diff --git a/core/res/assets/images/android-logo-mask.png b/core/res/assets/images/android-logo-mask.png
index 5512c0ad8a83..30d9e6f09e19 100644
Binary files a/core/res/assets/images/android-logo-mask.png and b/core/res/assets/images/android-logo-mask.png differ
diff --git a/core/res/assets/images/android-logo-shine.png b/core/res/assets/images/android-logo-shine.png
index c5d126392eeb..2ed7949fd910 100644
Binary files a/core/res/assets/images/android-logo-shine.png and b/core/res/assets/images/android-logo-shine.png differ
diff --git a/core/res/remote_color_resources_res/values/colors.xml b/core/res/remote_color_resources_res/values/colors.xml
index aff3a9592645..78a816b8ecba 100644
--- a/core/res/remote_color_resources_res/values/colors.xml
+++ b/core/res/remote_color_resources_res/values/colors.xml
@@ -66,4 +66,7 @@
#303030
#1b1b1b
#000000
+
+ #83f6e5
+ #00271e
diff --git a/core/res/remote_color_resources_res/values/public.xml b/core/res/remote_color_resources_res/values/public.xml
index 4b0a89202ad1..e1164df475b6 100644
--- a/core/res/remote_color_resources_res/values/public.xml
+++ b/core/res/remote_color_resources_res/values/public.xml
@@ -66,5 +66,8 @@
+
+
+
diff --git a/core/res/res/color/config_progress_background_tint.xml b/core/res/res/color/config_progress_background_tint.xml
index b086e20bf161..dfc914e76c8d 100644
--- a/core/res/res/color/config_progress_background_tint.xml
+++ b/core/res/res/color/config_progress_background_tint.xml
@@ -15,5 +15,5 @@
-->
-
+
diff --git a/core/res/res/color/surface_header_dark_sysui.xml b/core/res/res/color/surface_header_dark_sysui.xml
new file mode 100644
index 000000000000..ec070c96f91a
--- /dev/null
+++ b/core/res/res/color/surface_header_dark_sysui.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
index c9c72ba61947..4e7eb8ad4324 100644
Binary files a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png and b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png differ
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-hdpi/stat_sys_data_usb.png b/core/res/res/drawable-hdpi/stat_sys_data_usb.png
deleted file mode 100644
index f14f9080c121..000000000000
Binary files a/core/res/res/drawable-hdpi/stat_sys_data_usb.png and /dev/null differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_holo.9.png
deleted file mode 100644
index d57df98b5019..000000000000
Binary files a/core/res/res/drawable-hdpi/tab_selected_holo.9.png and /dev/null differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_data_usb.png b/core/res/res/drawable-ldpi/stat_sys_data_usb.png
deleted file mode 100644
index ffaccbde6952..000000000000
Binary files a/core/res/res/drawable-ldpi/stat_sys_data_usb.png and /dev/null differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
index 076fc1664217..97d250f889a2 100644
Binary files a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png and b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.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-mdpi/stat_sys_data_usb.png b/core/res/res/drawable-mdpi/stat_sys_data_usb.png
deleted file mode 100644
index 40d77f0a38f5..000000000000
Binary files a/core/res/res/drawable-mdpi/stat_sys_data_usb.png and /dev/null differ
diff --git a/core/res/res/drawable-mdpi/tab_selected_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_holo.9.png
deleted file mode 100644
index 587337caf74f..000000000000
Binary files a/core/res/res/drawable-mdpi/tab_selected_holo.9.png and /dev/null differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
index 97eb5fe801ea..a893b5790a6a 100644
Binary files a/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png and b/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.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-xhdpi/stat_sys_data_usb.png b/core/res/res/drawable-xhdpi/stat_sys_data_usb.png
deleted file mode 100644
index 57c1099d0d55..000000000000
Binary files a/core/res/res/drawable-xhdpi/stat_sys_data_usb.png and /dev/null differ
diff --git a/core/res/res/drawable-xhdpi/tab_selected_holo.9.png b/core/res/res/drawable-xhdpi/tab_selected_holo.9.png
deleted file mode 100644
index e4229f26b277..000000000000
Binary files a/core/res/res/drawable-xhdpi/tab_selected_holo.9.png and /dev/null differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png
index b7a99402eb58..3b6fa1a6c407 100644
Binary files a/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png and b/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.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-xxhdpi/stat_sys_data_usb.png b/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png
deleted file mode 100644
index 7fcf5cd999ab..000000000000
Binary files a/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png and /dev/null differ
diff --git a/core/res/res/drawable-xxhdpi/tab_selected_holo.9.png b/core/res/res/drawable-xxhdpi/tab_selected_holo.9.png
deleted file mode 100644
index bee35cad65f6..000000000000
Binary files a/core/res/res/drawable-xxhdpi/tab_selected_holo.9.png and /dev/null 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/core/res/res/drawable/ic_account_circle.xml b/core/res/res/drawable/ic_account_circle.xml
index 71691add7322..b83598c51fb7 100644
--- a/core/res/res/drawable/ic_account_circle.xml
+++ b/core/res/res/drawable/ic_account_circle.xml
@@ -20,8 +20,5 @@ Copyright (C) 2014 The Android Open Source Project
android:viewportHeight="24">
-
+ android:pathData="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M7.07,18.28C7.5,17.38 10.12,16.5 12,16.5C13.88,16.5 16.5,17.38 16.93,18.28C15.57,19.36 13.86,20 12,20C10.14,20 8.43,19.36 7.07,18.28M18.36,16.83C16.93,15.09 13.46,14.5 12,14.5C10.54,14.5 7.07,15.09 5.64,16.83C4.62,15.5 4,13.82 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,13.82 19.38,15.5 18.36,16.83M12,6C10.06,6 8.5,7.56 8.5,9.5C8.5,11.44 10.06,13 12,13C13.94,13 15.5,11.44 15.5,9.5C15.5,7.56 13.94,6 12,6M12,11A1.5,1.5 0 0,1 10.5,9.5A1.5,1.5 0 0,1 12,8A1.5,1.5 0 0,1 13.5,9.5A1.5,1.5 0 0,1 12,11Z" />
diff --git a/core/res/res/drawable/ic_audio_media.xml b/core/res/res/drawable/ic_audio_media.xml
index 4ef5340138b1..fd3c0deb75b6 100644
--- a/core/res/res/drawable/ic_audio_media.xml
+++ b/core/res/res/drawable/ic_audio_media.xml
@@ -22,7 +22,7 @@
+ android:pathData="M12,3l0.01,10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17V7h4V3H12zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
diff --git a/core/res/res/drawable/ic_audio_media_mute.xml b/core/res/res/drawable/ic_audio_media_mute.xml
index 2be6dc42af4d..210aee81451c 100644
--- a/core/res/res/drawable/ic_audio_media_mute.xml
+++ b/core/res/res/drawable/ic_audio_media_mute.xml
@@ -22,10 +22,10 @@
+ android:pathData="M21.19,21.19L14,14l-2,-2l-9.2,-9.2L1.39,4.22l8.79,8.79c-0.06,0 -0.12,-0.01 -0.18,-0.01C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17v-0.17l5.78,5.78L21.19,21.19zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
+ android:pathData="M14,11.17l0,-4.17l4,0l0,-4l-6,0l0,6.17z"/>
diff --git a/core/res/res/drawable/ic_audio_ring_notif.xml b/core/res/res/drawable/ic_audio_ring_notif.xml
index 54c4074771c2..47a08966aec2 100644
--- a/core/res/res/drawable/ic_audio_ring_notif.xml
+++ b/core/res/res/drawable/ic_audio_ring_notif.xml
@@ -22,5 +22,8 @@ Copyright (C) 2014 The Android Open Source Project
+ android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/>
+
diff --git a/core/res/res/drawable/ic_audio_ring_notif_mute.xml b/core/res/res/drawable/ic_audio_ring_notif_mute.xml
index b5915207b7f1..c838fe245d11 100644
--- a/core/res/res/drawable/ic_audio_ring_notif_mute.xml
+++ b/core/res/res/drawable/ic_audio_ring_notif_mute.xml
@@ -22,5 +22,11 @@ Copyright (C) 2014 The Android Open Source Project
+ android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+
+
diff --git a/core/res/res/drawable/ic_audio_vol.xml b/core/res/res/drawable/ic_audio_vol.xml
index fc216e5b699a..f66c316b897e 100644
--- a/core/res/res/drawable/ic_audio_vol.xml
+++ b/core/res/res/drawable/ic_audio_vol.xml
@@ -16,10 +16,10 @@ Copyright (C) 2014 The Android Open Source Project
+ android:pathData="M3 9v6h4l5 5V4L7 9H3zm7-0.17v6.34L7.83 13H5v-2h2.83L10 8.83zM16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-0.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89 0.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-0.91 7-4.49 7-8.77 0-4.28-2.99-7.86-7-8.77z" />
diff --git a/core/res/res/drawable/ic_audio_vol_mute.xml b/core/res/res/drawable/ic_audio_vol_mute.xml
index 7cf604c614be..d102676fe126 100644
--- a/core/res/res/drawable/ic_audio_vol_mute.xml
+++ b/core/res/res/drawable/ic_audio_vol_mute.xml
@@ -16,10 +16,10 @@ Copyright (C) 2014 The Android Open Source Project
+ android:pathData="M4.34 2.93L2.93 4.34 7.29 8.7 7 9H3v6h4l5 5v-6.59l4.18 4.18c-0.65 0.49 -1.38 0.88 -2.18 1.11v2.06c1.34-0.3 2.57-0.92 3.61-1.75l2.05 2.05 1.41-1.41L4.34 2.93zM10 15.17L7.83 13H5v-2h2.83l0.88-0.88L10 11.41v3.76zM19 12c0 0.82-0.15 1.61-0.41 2.34l1.53 1.53c0.56-1.17 0.88 -2.48 0.88 -3.87 0-4.28-2.99-7.86-7-8.77v2.06c2.89 0.86 5 3.54 5 6.71zm-7-8l-1.88 1.88L12 7.76zm4.5 8c0-1.77-1.02-3.29-2.5-4.03v1.79l2.48 2.48c0.01-0.08 0.02 -0.16 0.02 -0.24z" />
diff --git a/core/res/res/drawable/ic_battery.xml b/core/res/res/drawable/ic_battery.xml
index bd40f4df505e..318d125ed256 100644
--- a/core/res/res/drawable/ic_battery.xml
+++ b/core/res/res/drawable/ic_battery.xml
@@ -21,5 +21,5 @@
android:tint="?android:attr/colorControlNormal">
+ android:pathData="M16,20H8V6H16M16.67,4H15V2H9V4H7.33A1.33,1.33 0 0,0 6,5.33V20.67C6,21.4 6.6,22 7.33,22H16.67A1.33,1.33 0 0,0 18,20.67V5.33C18,4.6 17.4,4 16.67,4Z" />
diff --git a/core/res/res/drawable/ic_bt_headphones_a2dp.xml b/core/res/res/drawable/ic_bt_headphones_a2dp.xml
index 32f39a39754f..aa53b61387fb 100644
--- a/core/res/res/drawable/ic_bt_headphones_a2dp.xml
+++ b/core/res/res/drawable/ic_bt_headphones_a2dp.xml
@@ -21,6 +21,5 @@
android:tint="?android:attr/colorControlNormal">
+ android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4h2M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3h2m5,-13c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7c0,-4.97 -4.03,-9 -9,-9z" />
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_bt_headset_hfp.xml b/core/res/res/drawable/ic_bt_headset_hfp.xml
index e43fe39409af..f2066ed7c6cd 100644
--- a/core/res/res/drawable/ic_bt_headset_hfp.xml
+++ b/core/res/res/drawable/ic_bt_headset_hfp.xml
@@ -21,7 +21,5 @@
android:tint="?android:attr/colorControlNormal">
+ android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-1.71C5,6.45 7.96,3.11 11.79,3C15.76,2.89 19,6.06 19,10v2h-4v8h4v1h-6v2h6c1.1,0 2,-0.9 2,-2V10C21,5.03 16.97,1 12,1zM7,14v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7zM19,18h-2v-4h2V18z" />
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_bt_pointing_hid.xml b/core/res/res/drawable/ic_bt_pointing_hid.xml
index de97e249789f..470d1528b4fb 100644
--- a/core/res/res/drawable/ic_bt_pointing_hid.xml
+++ b/core/res/res/drawable/ic_bt_pointing_hid.xml
@@ -21,6 +21,5 @@
android:tint="?android:attr/colorControlNormal">
+ android:pathData="M20 9c-0.04-4.39-3.6-7.93-8-7.93S4.04 4.61 4 9v6c0 4.42 3.58 8 8 8s8-3.58 8-8V9zm-2 0h-5V3.16c2.81 0.47 4.96 2.9 5 5.84zm-7-5.84V9H6c0.04-2.94 2.19-5.37 5-5.84zM18 15c0 3.31-2.69 6-6 6s-6-2.69-6-6v-4h12v4z" />
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_doc_folder.xml b/core/res/res/drawable/ic_doc_folder.xml
index dcbce010810e..ac29ba665609 100644
--- a/core/res/res/drawable/ic_doc_folder.xml
+++ b/core/res/res/drawable/ic_doc_folder.xml
@@ -20,5 +20,5 @@ Copyright (C) 2015 The Android Open Source Project
android:viewportHeight="24.0">
+ android:pathData="M20,18H4V8H20M20,6H12L10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6Z" />
diff --git a/core/res/res/drawable/ic_eject_24dp.xml b/core/res/res/drawable/ic_eject_24dp.xml
index 321ee3b6289c..d01461aa0232 100644
--- a/core/res/res/drawable/ic_eject_24dp.xml
+++ b/core/res/res/drawable/ic_eject_24dp.xml
@@ -20,8 +20,5 @@ Copyright (C) 2015 The Android Open Source Project
android:viewportHeight="24.0">
-
+ android:pathData="M5,17H19V19H5V17M12,5L5.33,15H18.67L12,5M12,8.6L14.93,13H9.07L12,8.6Z" />
diff --git a/core/res/res/drawable/ic_file_copy.xml b/core/res/res/drawable/ic_file_copy.xml
index d05b55f1279f..01dff735a402 100644
--- a/core/res/res/drawable/ic_file_copy.xml
+++ b/core/res/res/drawable/ic_file_copy.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/ic_folder_24dp.xml b/core/res/res/drawable/ic_folder_24dp.xml
index 9a386ca45e7a..b6d8a1bbf9c6 100644
--- a/core/res/res/drawable/ic_folder_24dp.xml
+++ b/core/res/res/drawable/ic_folder_24dp.xml
@@ -16,9 +16,9 @@ Copyright (C) 2015 The Android Open Source Project
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:pathData="M20,18H4V8H20M20,6H12L10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6Z" />
diff --git a/core/res/res/drawable/ic_lock_lockdown.xml b/core/res/res/drawable/ic_lock_lockdown.xml
index b9685d3e7cca..6c6a676a6d35 100644
--- a/core/res/res/drawable/ic_lock_lockdown.xml
+++ b/core/res/res/drawable/ic_lock_lockdown.xml
@@ -22,5 +22,5 @@ Copyright (C) 2018 The Android Open Source Project
+ android:pathData="M12,17C10.89,17 10,16.1 10,15C10,13.89 10.89,13 12,13A2,2 0 0,1 14,15A2,2 0 0,1 12,17M18,20V10H6V20H18M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10C4,8.89 4.89,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z" />
diff --git a/core/res/res/drawable/ic_lockscreen_ime.xml b/core/res/res/drawable/ic_lockscreen_ime.xml
index 4b81a3c9c460..90492770c5bd 100644
--- a/core/res/res/drawable/ic_lockscreen_ime.xml
+++ b/core/res/res/drawable/ic_lockscreen_ime.xml
@@ -21,6 +21,5 @@
android:tint="?android:attr/colorControlNormal">
+ android:pathData="M4,5A2,2 0 0,0 2,7V17A2,2 0 0,0 4,19H20A2,2 0 0,0 22,17V7A2,2 0 0,0 20,5H4M4,7H20V17H4V7M5,8V10H7V8H5M8,8V10H10V8H8M11,8V10H13V8H11M14,8V10H16V8H14M17,8V10H19V8H17M5,11V13H7V11H5M8,11V13H10V11H8M11,11V13H13V11H11M14,11V13H16V11H14M17,11V13H19V11H17M8,14V16H16V14H8Z" />
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_notification_alert.xml b/core/res/res/drawable/ic_notification_alert.xml
index c8514acde2ac..f9bd88a9faa7 100644
--- a/core/res/res/drawable/ic_notification_alert.xml
+++ b/core/res/res/drawable/ic_notification_alert.xml
@@ -25,9 +25,6 @@ Copyright (C) 2016 The Android Open Source Project
android:pathData="M7.1,3.6L5.7,2.2C3.3,4.0 1.7,6.8 1.5,10.0l2.0,0.0C3.7,7.3 5.0,5.0 7.1,3.6z"
android:fillColor="#FFFFFFFF"/>
-
diff --git a/core/res/res/drawable/ic_notifications_alerted.xml b/core/res/res/drawable/ic_notifications_alerted.xml
index 4bfac37e8408..6bbca37cd48c 100644
--- a/core/res/res/drawable/ic_notifications_alerted.xml
+++ b/core/res/res/drawable/ic_notifications_alerted.xml
@@ -19,6 +19,9 @@ Copyright (C) 2018 The Android Open Source Project
android:viewportWidth="24.0"
android:viewportHeight="24.0">
+
diff --git a/core/res/res/drawable/ic_parallel_badge.xml b/core/res/res/drawable/ic_parallel_badge.xml
new file mode 100644
index 000000000000..3c5734c7e0fc
--- /dev/null
+++ b/core/res/res/drawable/ic_parallel_badge.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
diff --git a/core/res/res/drawable/ic_parallel_icon_badge.xml b/core/res/res/drawable/ic_parallel_icon_badge.xml
new file mode 100644
index 000000000000..c86ca733de04
--- /dev/null
+++ b/core/res/res/drawable/ic_parallel_icon_badge.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/drawable/ic_perm_device_info.xml b/core/res/res/drawable/ic_perm_device_info.xml
index ef91c74620ac..b546992bd39d 100644
--- a/core/res/res/drawable/ic_perm_device_info.xml
+++ b/core/res/res/drawable/ic_perm_device_info.xml
@@ -16,9 +16,9 @@
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7v-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM11,7h2v2h-2V7zM11,11h2v6h-2V11z"/>
diff --git a/core/res/res/drawable/ic_phone.xml b/core/res/res/drawable/ic_phone.xml
index be9b094134c8..27ada123149f 100644
--- a/core/res/res/drawable/ic_phone.xml
+++ b/core/res/res/drawable/ic_phone.xml
@@ -22,8 +22,5 @@
android:autoMirrored="true">
+ android:pathData="M6.54 5c0.06 0.89 0.21 1.76 0.45 2.59l-1.2 1.2c-0.41-1.2-0.67-2.47-0.76-3.79h1.51m9.86 12.02c0.85 0.24 1.72 0.39 2.6 0.45 v1.49c-1.32-0.09-2.59-0.35-3.8-0.75l1.2-1.19M7.5 3H4c-0.55 0-1 0.45-1 1 0 9.39 7.61 17 17 17 0.55 0 1-0.45 1-1v-3.49c0-0.55-0.45-1-1-1-1.24 0-2.45-0.2-3.57-0.57-0.1-0.04-0.21-0.05-0.31-0.05-0.26 0-0.51 0.1 -0.71 0.29 l-2.2 2.2c-2.83-1.45-5.15-3.76-6.59-6.59l2.2-2.2c0.28-0.28 0.36 -0.67 0.25 -1.02C8.7 6.45 8.5 5.25 8.5 4c0-0.55-0.45-1-1-1z" />
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_pocket_lock.xml b/core/res/res/drawable/ic_pocket_lock.xml
new file mode 100644
index 000000000000..3494a8f38b84
--- /dev/null
+++ b/core/res/res/drawable/ic_pocket_lock.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/core/res/res/drawable/ic_print.xml b/core/res/res/drawable/ic_print.xml
index 7aa251300448..b72b4d02946e 100644
--- a/core/res/res/drawable/ic_print.xml
+++ b/core/res/res/drawable/ic_print.xml
@@ -21,6 +21,9 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
+
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_print_error.xml b/core/res/res/drawable/ic_print_error.xml
index 37e51527e399..999e92e39e07 100644
--- a/core/res/res/drawable/ic_print_error.xml
+++ b/core/res/res/drawable/ic_print_error.xml
@@ -21,6 +21,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_qs_night_display_on.xml b/core/res/res/drawable/ic_qs_night_display_on.xml
index a4755ee256e2..68004f168f2e 100644
--- a/core/res/res/drawable/ic_qs_night_display_on.xml
+++ b/core/res/res/drawable/ic_qs_night_display_on.xml
@@ -21,6 +21,6 @@
+ android:pathData="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z" />
diff --git a/core/res/res/drawable/ic_sd_card_48dp.xml b/core/res/res/drawable/ic_sd_card_48dp.xml
index 10fd12054820..f3927e95cb22 100644
--- a/core/res/res/drawable/ic_sd_card_48dp.xml
+++ b/core/res/res/drawable/ic_sd_card_48dp.xml
@@ -16,9 +16,9 @@ Copyright (C) 2015 The Android Open Source Project
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:pathData="M18 4v16H6V8.83L10.83 4H18m0-2h-8L4 8v12c0 1.1 0.9 2 2 2h12c1.1 0 2-0.9 2-2V4c0-1.1-0.9-2-2-2zM9 7h2v4H9zm3 0h2v4h-2zm3 0h2v4h-2z"/>
diff --git a/core/res/res/drawable/ic_settings_print.xml b/core/res/res/drawable/ic_settings_print.xml
index 68b627cf4dc9..b77e6ba0f2d8 100644
--- a/core/res/res/drawable/ic_settings_print.xml
+++ b/core/res/res/drawable/ic_settings_print.xml
@@ -21,5 +21,8 @@
android:tint="?android:attr/colorControlNormal">
+ android:pathData="M19 8h-1V3H6v5H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zM8 5h8v3H8V5zm8 12v2H8v-4h8v2zm2-2v-2H6v2H4v-4c0-0.55 0.45 -1 1-1h14c0.55 0 1 0.45 1 1v4h-2z" />
+
diff --git a/core/res/res/drawable/ic_voice_search_api_material.xml b/core/res/res/drawable/ic_voice_search_api_material.xml
index a02621820b62..5aa5b56faa2d 100644
--- a/core/res/res/drawable/ic_voice_search_api_material.xml
+++ b/core/res/res/drawable/ic_voice_search_api_material.xml
@@ -20,6 +20,9 @@ Copyright (C) 2014 The Android Open Source Project
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
+
diff --git a/core/res/res/drawable/perm_group_call_log.xml b/core/res/res/drawable/perm_group_call_log.xml
index a37ed88bebfc..e60770f7b160 100644
--- a/core/res/res/drawable/perm_group_call_log.xml
+++ b/core/res/res/drawable/perm_group_call_log.xml
@@ -23,7 +23,7 @@
android:viewportHeight="24.0">
+ android:pathData="M6.54 5c0.06 0.89 0.21 1.76 0.45 2.59l-1.2 1.2c-0.41-1.2-0.67-2.47-0.76-3.79h1.51m9.86 12.02c0.85 0.24 1.72 0.39 2.6 0.45 v1.49c-1.32-0.09-2.59-0.35-3.8-0.75l1.2-1.19M7.5 3H4c-0.55 0-1 0.45-1 1 0 9.39 7.61 17 17 17 0.55 0 1-0.45 1-1v-3.49c0-0.55-0.45-1-1-1-1.24 0-2.45-0.2-3.57-0.57-0.1-0.04-0.21-0.05-0.31-0.05-0.26 0-0.51 0.1 -0.71 0.29 l-2.2 2.2c-2.83-1.45-5.15-3.76-6.59-6.59l2.2-2.2c0.28-0.28 0.36 -0.67 0.25 -1.02C8.7 6.45 8.5 5.25 8.5 4c0-0.55-0.45-1-1-1z" />
diff --git a/core/res/res/drawable/perm_group_phone_calls.xml b/core/res/res/drawable/perm_group_phone_calls.xml
index 563222698b46..ff4c138013b1 100644
--- a/core/res/res/drawable/perm_group_phone_calls.xml
+++ b/core/res/res/drawable/perm_group_phone_calls.xml
@@ -22,8 +22,5 @@
android:viewportHeight="24">
+ android:pathData="M6.54 5c0.06 0.89 0.21 1.76 0.45 2.59l-1.2 1.2c-0.41-1.2-0.67-2.47-0.76-3.79h1.51m9.86 12.02c0.85 0.24 1.72 0.39 2.6 0.45 v1.49c-1.32-0.09-2.59-0.35-3.8-0.75l1.2-1.19M7.5 3H4c-0.55 0-1 0.45-1 1 0 9.39 7.61 17 17 17 0.55 0 1-0.45 1-1v-3.49c0-0.55-0.45-1-1-1-1.24 0-2.45-0.2-3.57-0.57-0.1-0.04-0.21-0.05-0.31-0.05-0.26 0-0.51 0.1 -0.71 0.29 l-2.2 2.2c-2.83-1.45-5.15-3.76-6.59-6.59l2.2-2.2c0.28-0.28 0.36 -0.67 0.25 -1.02C8.7 6.45 8.5 5.25 8.5 4c0-0.55-0.45-1-1-1z" />
diff --git a/core/res/res/drawable/pocket_mode_img.xml b/core/res/res/drawable/pocket_mode_img.xml
new file mode 100644
index 000000000000..81bb727f0bd3
--- /dev/null
+++ b/core/res/res/drawable/pocket_mode_img.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/core/res/res/drawable/stat_sys_data_usb.xml b/core/res/res/drawable/stat_sys_data_usb.xml
new file mode 100644
index 000000000000..fb1ad2a47706
--- /dev/null
+++ b/core/res/res/drawable/stat_sys_data_usb.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/core/res/res/drawable/sym_def_app_icon.xml b/core/res/res/drawable/sym_def_app_icon.xml
index 129d38a74750..38d91477fbce 100644
--- a/core/res/res/drawable/sym_def_app_icon.xml
+++ b/core/res/res/drawable/sym_def_app_icon.xml
@@ -1,7 +1,19 @@
+
-
-
-
+
diff --git a/core/res/res/drawable/sym_def_app_icon_foreground.xml b/core/res/res/drawable/sym_def_app_icon_foreground.xml
new file mode 100644
index 000000000000..0a5a334d10f7
--- /dev/null
+++ b/core/res/res/drawable/sym_def_app_icon_foreground.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/drawable/tab_selected_holo.xml b/core/res/res/drawable/tab_selected_holo.xml
new file mode 100644
index 000000000000..af20790beb5c
--- /dev/null
+++ b/core/res/res/drawable/tab_selected_holo.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/core/res/res/layout/accessibility_enable_service_warning.xml b/core/res/res/layout/accessibility_enable_service_warning.xml
index 01ef10177c5a..84520a28228f 100644
--- a/core/res/res/layout/accessibility_enable_service_warning.xml
+++ b/core/res/res/layout/accessibility_enable_service_warning.xml
@@ -51,7 +51,7 @@
android:gravity="center"
android:textSize="20sp"
android:textColor="?android:attr/textColorPrimary"
- android:fontFamily="google-sans-medium"/>
+ android:fontFamily="@string/config_headlineFontFamilyMedium"/>
-
-
+
+
-
+
+
-
-
-
-
\ No newline at end of file
+ android:layout_gravity="top|center_horizontal"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorTertiary"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ />
+
diff --git a/core/res/res/layout/global_actions_silent_mode.xml b/core/res/res/layout/global_actions_silent_mode.xml
index a3586232a152..dbdb638a37df 100644
--- a/core/res/res/layout/global_actions_silent_mode.xml
+++ b/core/res/res/layout/global_actions_silent_mode.xml
@@ -17,26 +17,26 @@
-
\ No newline at end of file
+
diff --git a/core/res/res/layout/pocket_lock_view.xml b/core/res/res/layout/pocket_lock_view.xml
new file mode 100644
index 000000000000..53eb560d5a04
--- /dev/null
+++ b/core/res/res/layout/pocket_lock_view.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/layout/time_picker_material.xml b/core/res/res/layout/time_picker_material.xml
index 75973798219e..ee733f1f39e8 100644
--- a/core/res/res/layout/time_picker_material.xml
+++ b/core/res/res/layout/time_picker_material.xml
@@ -44,7 +44,7 @@
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:includeFontPadding="false"
- android:fontFamily="sans-serif-medium"
+ android:fontFamily="@string/config_bodyFontFamilyMedium"
android:textSize="34sp"
android:textColor="@color/white"
android:text="@string/time_picker_header_text"/>
diff --git a/core/res/res/mipmap-hdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-hdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 4e526c95b4d6..000000000000
Binary files a/core/res/res/mipmap-hdpi/sym_def_app_icon_foreground.png and /dev/null differ
diff --git a/core/res/res/mipmap-mdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-mdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 2c38c719088d..000000000000
Binary files a/core/res/res/mipmap-mdpi/sym_def_app_icon_foreground.png and /dev/null differ
diff --git a/core/res/res/mipmap-xhdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-xhdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 072467eaaafb..000000000000
Binary files a/core/res/res/mipmap-xhdpi/sym_def_app_icon_foreground.png and /dev/null differ
diff --git a/core/res/res/mipmap-xxhdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-xxhdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 78a6b7a3464d..000000000000
Binary files a/core/res/res/mipmap-xxhdpi/sym_def_app_icon_foreground.png and /dev/null differ
diff --git a/core/res/res/mipmap-xxxhdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-xxxhdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 68ebe33fe237..000000000000
Binary files a/core/res/res/mipmap-xxxhdpi/sym_def_app_icon_foreground.png and /dev/null differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8fb09fc31834..74ff08fd0db0 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -663,8 +663,6 @@
"Kan nie jou gesigmodel skep nie. Probeer weer."
"Donkerbril bespeur. Jou gesig moet heeltemal sigbaar wees."
"Gesigbedekking bespeur. Jou gesig moet heeltemal sigbaar wees."
-
-
"Kan nie gesig verifieer nie. Hardeware nie beskikbaar nie."
"Probeer Gesigslot weer"
"Kan nie nuwe gesigdata berg nie. Vee eers \'n ou een uit."
@@ -682,8 +680,6 @@
"Gebruik Gesigslot of Skermslot"
"Gebruik jou gesig om voort te gaan"
"Gebruik jou gesig of skermslot om voort te gaan"
-
-
"Iets is fout. Probeer weer."
"Gesig-ikoon"
"lees sinkroniseer-instellings"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f47cf3fd77bd..b44e452f7a60 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -663,8 +663,6 @@
"የመልክዎን ሞዴል መፍጠር አልተቻለም። እንደገና ይሞክሩ።"
"ጠቆር ያሉ መነጽሮች ተገኝተዋል። መልክዎ ሙሉ በሙሉ መታየት አለበት።"
"የመልክ መሸፈኛ ተገኝቷል። መልክዎ ሙሉ በሙሉ መታየት አለበት።"
-
-
"መልክን ማረጋገጥ አይቻልም። ሃርድዌር የለም።"
"በመልክ መክፈትን እንደገና ይሞክሩ"
"አዲስ የመልክ ውውሂብ ማስቀመጥ አልተቻለም። መጀመሪያ የድሮውን ይሰርዙት።"
@@ -682,8 +680,6 @@
"የመልክ ወይም የማያ ገጽ መቆለፊያን ይጠቀሙ"
"ለመቀጠል መልክዎን ይጠቀሙ"
"ለመቀጠል መልክዎን ወይም የማያ ገጽዎን መቆለፊያ ይጠቀሙ"
-
-
"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"
"የፊት አዶ"
"የሥምሪያ ቅንብሮች አንብብ"
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 8d47c17704bc..6b304597212e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -667,8 +667,6 @@
"يتعذّر إنشاء نموذج الوجه. يُرجى إعادة المحاولة."
"تمّ رصد نظارة شمسية. يجب أن يكون وجهك ظاهرًا بالكامل."
"تمّ رصد قناع على الوجه. يجب أن يكون وجهك ظاهرًا بالكامل."
-
-
"يتعذّر التحقُّق من الوجه. الجهاز غير مُتاح."
"جرِّب \"فتح الجهاز بالتعرف على الوجه\" مرة أخرى."
"يتعذَّر تخزين بيانات الوجه الجديد. احذف الوجه القديم أولاً."
@@ -686,8 +684,6 @@
"استخدام ميزة \"فتح الجهاز بالتعرف على الوجه\" أو ميزة \"قفل الشاشة\""
"استخدِم الوجه للمتابعة"
"استخدام ميزة \"فتح القفل بالوجه\" أو ميزة \"قفل الشاشة\" للمتابعة"
-
-
"حدث خطأ، يُرجى إعادة المحاولة."
"رمز الوجه"
"قراءة إعدادات المزامنة"
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index f5fbba9a7b7a..5d544b9f8bd1 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -663,8 +663,6 @@
"মুখাৱয়বৰ মডেল সৃষ্টি কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"
"ডাঠ ৰঙৰ চশমা চিনাক্ত কৰা হৈছে। আপোনাৰ মুখাৱয়ব সম্পূৰ্ণৰূপে দেখা পোৱা হৈ থাকিবই লাগিব।"
"মুখাৱয়বত আৱৰণ চিনাক্ত কৰা হৈছে। আপোনাৰ মুখাৱয়ব সম্পূৰ্ণৰূপে দেখা পোৱা হৈ থাকিবই লাগিব।"
-
-
"মুখমণ্ডল সত্যাপন কৰিব পৰা নগ’ল। হাৰ্ডৱেৰ নাই।"
"ফেচ আনলক পুনৰ ব্যৱহাৰ কৰি চাওক"
"নতুন মুখমণ্ডলৰ ডেটা জমা কৰিব পৰা নাই। প্ৰথমে পুৰণি এখন মচক।"
@@ -682,8 +680,6 @@
"ফেচ আনলক অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"
"অব্যাহত ৰাখিবলৈ নিজৰ মুখাৱয়ব ব্যৱহাৰ কৰক"
"অব্যাহত ৰাখিবলৈ আপোনাৰ মুখাৱয়ব অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"
-
-
"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"
"মুখমণ্ডলৰ আইকন"
"ছিংকৰ ছেটিং পঢ়ক"
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index bc6aa16ba19f..02de906151dd 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -663,8 +663,6 @@
"Üz modelinizi yaratmaq olmur. Yenə cəhd edin."
"Tünd eynək aşkar edildi. Üzünüz tam görünməlidir."
"Üz örtüyü aşkar edildi. Üzünüz tam görünməlidir."
-
-
"Üz doğrulanmadı. Avadanlıq əlçatan deyil."
"Üz ilə kiliddən çıxarmanı yenidən sınayın"
"Yeni üz datası saxlanmadı. Əvvəlcə köhnə olanı silin."
@@ -682,8 +680,6 @@
"Üz və ya ekran kilidindən istifadə edin"
"Davam etmək üçün üzünüzdən istifadə edin"
"Davam etmək üçün üz və ya ekran kilidinizdən istifadə edin"
-
-
"Xəta oldu. Yenə cəhd edin."
"Üz işarəsi"
"sinx ayarlarını oxu"
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index d0e2a3c13e7b..10f007e9e9d3 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -664,8 +664,6 @@
"Pravljenje modela lica nije uspelo. Probajte ponovo."
"Otkrivene su tamne naočari. Lice mora da bude potpuno vidljivo."
"Otkriveno je prekrivanje lica. Lice mora da bude potpuno vidljivo."
-
-
"Provera lica nije uspela. Hardver nije dostupan."
"Probajte ponovo otključavanje licem"
"Novi podaci o licu nisu sačuvani. Prvo izbrišete prethodne."
@@ -683,8 +681,6 @@
"Koristite zaključavanje licem ili zaključavanje ekrana"
"Potvrdite identitet licem da biste nastavili"
"Koristite lice ili zaključavanje ekrana da biste nastavili"
-
-
"Došlo je do problema. Probajte ponovo."
"Ikona lica"
"čitanje podešavanja sinhronizacije"
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index b3e4fc3fd2e9..a5ed30089d2b 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -665,8 +665,6 @@
"Не ўдалося стварыць мадэль твару. Паўтарыце спробу."
"Выяўлены цёмныя акуляры. Твар павінен быць цалкам бачным."
"Нешта засланяе твар. Твар павінен быць цалкам бачным."
-
-
"Твар не спраўджаны. Абсталяванне недаступнае."
"Выканайце распазнаванне твару паўторна"
"Новыя даныя пра твар не захаваны. Спачатку выдаліце старыя."
@@ -684,8 +682,6 @@
"Выкарыстоўваць распазнаванне твару ці блакіроўку экрана"
"Каб працягнуць, скарыстайце распазнаванне твару"
"Каб працягнуць, скарыстайце распазнаванне твару ці сродак разблакіроўкі экрана"
-
-
"Нешта пайшло не так. Паўтарыце спробу."
"Значок твару"
"чытаць параметры сінхранізацыі"
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7d21ba3eb29a..98fe6714b2a4 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -663,8 +663,6 @@
"Моделът на лицето ви не бе създаден. Опитайте отново."
"Изглежда, че носите тъмни очила. То трябва да е напълно видимо."
"Изглежда, че лицето ви е покрито. То трябва да е напълно видимо."
-
-
"Лицето не може да се потвърди. Хардуерът не е налице."
"Опитайте отново да отключите с лице"
"Не може да се запази ново лице. Първо изтрийте старо."
@@ -682,8 +680,6 @@
"Използване на отключването с лице или опцията за заключване на екрана"
"Използвайте лицето си, за да продължите"
"Използвайте лицето си или опцията за заключване на екрана, за да продължите"
-
-
"Нещо се обърка. Опитайте отново."
"Икона на лице"
"четене на настройките за синхронизиране"
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 6da6267e5b03..cf47e85fe71b 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -663,8 +663,6 @@
"ফেস মডেল তৈরি করা যাচ্ছে না। আবার চেষ্টা করুন।"
"কালো চশমা শনাক্ত করা হয়েছে। আপনার মুখ পুরোপুরি দৃশ্যমান হতে হবে।"
"মুখে মাস্ক শনাক্ত করা হয়েছে। আপনার মুখ পুরোপুরি দৃশ্যমান হতে হবে।"
-
-
"ফেস যাচাই করা যায়নি। হার্ডওয়্যার উপলভ্য নেই।"
"\'ফেস আনলক\' আবার ব্যবহার করার চেষ্টা করুন"
"নতুন ফেস ডেটা স্টোর করা যায়নি। প্রথমে পুরনোটি মুছে ফেলুন।"
@@ -682,8 +680,6 @@
"ফেস অথবা স্ক্রিন লক ব্যবহার করুন"
"চালিয়ে যেতে আপনার মুখ ব্যবহার করুন"
"চালিয়ে যেতে আপনার ফেস বা স্ক্রিন লক ব্যবহার করুন"
-
-
"কোনও সমস্যা হয়েছে। আবার করে দেখুন।"
"ফেস আইকন"
"সিঙ্ক সেটিংস পড়ে"
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index e59733079b44..a036a14d2e78 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -664,8 +664,6 @@
"Nije moguće kreirati model lica. Pokušajte ponovo."
"Otkrivene su tamne naočale. Lice se mora u potpunosti vidjeti."
"Otkriveno je pokrivalo preko lica. Lice se mora u potpunosti vidjeti."
-
-
"Nije moguće potvrditi lice. Hardver nije dostupan."
"Pokušajte ponovo s otključavanjem licem"
"Nije moguće sačuvati nove podatke o licu. Prvo izbrišite stare."
@@ -683,8 +681,6 @@
"Koristi otključavanje licem ili zaključavanje ekrana"
"Koristite lice da nastavite"
"Koristite lice ili zaključavanje ekrana da nastavite"
-
-
"Nešto nije uredu. Pokušajte ponovo."
"Ikona lica"
"čitanje postavki za sinhroniziranje"
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a5ed4e9674ad..c57f0850150b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -663,8 +663,6 @@
"No es pot crear el model facial. Torna-ho a provar."
"S\'han detectat ulleres fosques. La cara ha de ser completament visible."
"S\'ha detectat una mascareta. La cara ha de ser completament visible."
-
-
"No es pot verificar la cara. Maquinari no disponible."
"Torna a provar Desbloqueig facial"
"No es poden desar dades facials noves. Suprimeix-ne d\'antigues."
@@ -682,8 +680,6 @@
"Utilitza el desbloqueig facial o de pantalla"
"Utilitza la teva cara per continuar"
"Utilitza la cara o el bloqueig de pantalla per continuar"
-
-
"S\'ha produït un error. Torna-ho a provar."
"Icona facial"
"llegir la configuració de sincronització"
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 21b147d81433..3466ea15e3ef 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -665,8 +665,6 @@
"Model se nepodařilo vytvořit. Zkuste to znovu."
"Byly zjištěny tmavé brýle. Obličej musí být plně viditelný."
"Byl zjištěn zakrytý obličej. Obličej musí být plně viditelný."
-
-
"Obličej nelze ověřit. Hardware není dostupný."
"Zopakujte odemknutí obličejem"
"Údaje o novém obličeji nelze uložit. Nejdřív vymažte starý."
@@ -684,8 +682,6 @@
"Použít odemknutí obličejem nebo zámek obrazovky"
"Pokračujte ověřením obličeje"
"Pokračujte ověřením pomocí obličeje nebo zámku obrazovky"
-
-
"Došlo k chybě. Zkuste to znovu."
"Ikona obličeje"
"čtení nastavení synchronizace"
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index b04d8c9c1115..c8de8256bb46 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -663,8 +663,6 @@
"Din ansigtsmodel kan ikke oprettes. Prøv igen."
"Mørke briller er registreret. Dit ansigt skal være helt synligt."
"Ansigtsdækning er registreret. Dit ansigt skal være helt synligt."
-
-
"Ansigt ikke bekræftet. Hardware ikke tilgængelig."
"Prøv ansigtslås igen"
"Der kan ikke gemmes nye ansigtsdata. Slet et gammelt først."
@@ -682,8 +680,6 @@
"Brug ansigts- eller skærmlås"
"Brug dit ansigt for at fortsætte"
"Brug din ansigts- eller skærmlås for at fortsætte"
-
-
"Noget gik galt. Prøv igen."
"Ansigt"
"læse indstillinger for synkronisering"
diff --git a/core/res/res/values-de/bootleg_strings.xml b/core/res/res/values-de/bootleg_strings.xml
new file mode 100644
index 000000000000..c41c67aaf911
--- /dev/null
+++ b/core/res/res/values-de/bootleg_strings.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Bootloader-Neustart
+ Neustart in Bootloader-Modus\u2026
+ Recovery-Neustart
+ Neustart in Recovery-Modus\u2026
+ System-Neustart
+ System-Neustart
+
+
+
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index dc9d746459cd..ab68c5fa2119 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -663,8 +663,6 @@
"Dein Gesichtsmodell kann nicht erstellt werden. Versuche es noch einmal."
"Dunkle Brille erkannt. Dein Gesicht muss vollständig sichtbar sein."
"Dein Gesicht ist bedeckt. Es muss vollständig sichtbar sein."
-
-
"Gesicht nicht erkannt. Hardware nicht verfügbar."
"Versuche es noch mal mit der Gesichtsentsperrung"
"Kein Speicherplatz frei. Bitte erst ein Gesicht löschen."
@@ -682,8 +680,6 @@
"Entsperrung per Gesichtserkennung oder Displaysperre verwenden"
"Gesichtserkennung verwenden, um fortzufahren"
"Verwende die Gesichtserkennung oder deine Display-Entsperrmethode, um fortzufahren"
-
-
"Ein Problem ist aufgetreten. Versuch es noch einmal."
"Gesichtssymbol"
"Synchronisierungseinstellungen lesen"
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 1fcf94e73024..4a9540728198 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -663,8 +663,6 @@
"Αδύνατη η δημιουργία του μοντέλου προσώπου. Δοκιμάστε ξανά."
"Ανιχνεύτηκαν σκούρα γυαλιά. Το πρόσωπό σας πρέπει να φαίνεται πλήρως."
"Ανιχνεύτηκε κάλυμμα προσώπου. Το πρόσωπό σας πρέπει να φαίνεται πλήρως."
-
-
"Αδύν. επαλήθ. προσώπου. Μη διαθέσιμος εξοπλισμός."
"Δοκιμάστε ξανά το Ξεκλείδωμα με το πρόσωπο"
"Η αποθήκ. νέων δεδομ. προσώπ. είναι αδύν. Διαγρ. ένα παλιό."
@@ -682,8 +680,6 @@
"Χρήση προσώπου ή κλειδώματος οθόνης"
"Χρησιμοποιήστε το πρόσωπό σας για να συνεχίσετε"
"Χρησιμοποιήστε το πρόσωπό σας ή το κλείδωμα οθόνης για συνέχεια"
-
-
"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά."
"Εικ. προσ."
"διαβάζει τις ρυθμίσεις συγχρονισμού"
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index bde1fe019faf..6e174ee3ec5b 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -663,8 +663,6 @@
"Can’t create your face model. Try again."
"Dark glasses detected. Your face must be fully visible."
"Face covering detected. Your face must be fully visible."
-
-
"Can’t verify face. Hardware not available."
"Try Face Unlock again"
"Can’t store new face data. Delete an old one first."
@@ -682,8 +680,6 @@
"Use face or screen lock"
"Use your face to continue"
"Use your face or screen lock to continue"
-
-
"Something went wrong. Try again."
"Face icon"
"read sync settings"
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index cbed459307a2..5ae24c24ec48 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -663,8 +663,6 @@
"Can’t create your face model. Try again."
"Dark glasses detected. Your face must be fully visible."
"Face covering detected. Your face must be fully visible."
-
-
"Can’t verify face. Hardware not available."
"Try Face Unlock again"
"Can’t store new face data. Delete an old one first."
@@ -682,8 +680,6 @@
"Use face or screen lock"
"Use your face to continue"
"Use your face or screen lock to continue"
-
-
"Something went wrong. Try again."
"Face icon"
"read sync settings"
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index fcd40c541579..dcd815864f8e 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -663,8 +663,6 @@
"Can’t create your face model. Try again."
"Dark glasses detected. Your face must be fully visible."
"Face covering detected. Your face must be fully visible."
-
-
"Can’t verify face. Hardware not available."
"Try Face Unlock again"
"Can’t store new face data. Delete an old one first."
@@ -682,8 +680,6 @@
"Use face or screen lock"
"Use your face to continue"
"Use your face or screen lock to continue"
-
-
"Something went wrong. Try again."
"Face icon"
"read sync settings"
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e583cefc8bd8..37a40ecb7f8f 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -663,8 +663,6 @@
"Can’t create your face model. Try again."
"Dark glasses detected. Your face must be fully visible."
"Face covering detected. Your face must be fully visible."
-
-
"Can’t verify face. Hardware not available."
"Try Face Unlock again"
"Can’t store new face data. Delete an old one first."
@@ -682,8 +680,6 @@
"Use face or screen lock"
"Use your face to continue"
"Use your face or screen lock to continue"
-
-
"Something went wrong. Try again."
"Face icon"
"read sync settings"
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 77a1af62382a..d3c9cc4eafb2 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -663,8 +663,6 @@
"Can’t create your face model. Try again."
"Dark glasses detected. Your face must be fully visible."
"Face covering detected. Your face must be fully visible."
-
-
"Can’t verify face. Hardware not available."
"Try Face Unlock again"
"Can’t store new face data. Delete an old one first."
@@ -682,8 +680,6 @@
"Use face or screen lock"
"Use your face to continue"
"Use your face or screen lock to continue"
-
-
"Something went wrong. Try again."
"Face icon"
"read sync settings"
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2a3f916dcdec..059b4d1500b2 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -664,8 +664,6 @@
"No se puede crear modelo de rostro. Vuelve a intentarlo."
"Se detectaron lentes oscuros. Tu rostro debe verse completamente."
"Se detectó que llevas mascarilla. Tu rostro debe verse completamente."
-
-
"No se verificó el rostro. Hardware no disponible."
"Vuelve a probar Desbloqueo facial"
"No hay espacio para datos faciales nuevos. Borra uno viejo."
@@ -683,8 +681,6 @@
"Usar desbloqueo facial o de pantalla"
"Usa el rostro para continuar"
"Usa tu rostro o bloqueo de pantalla para continuar"
-
-
"Se produjo un error. Vuelve a intentarlo."
"Ícono cara"
"leer la configuración de sincronización"
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0969a5fa0fce..5c39aa74d513 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -664,8 +664,6 @@
"No se puede crear tu modelo. Inténtalo de nuevo."
"Gafas oscuras detectadas. Tu cara se debe poder ver por completo."
"Mascarilla detectada. Tu cara se debe poder ver por completo."
-
-
"No se puede verificar. Hardware no disponible."
"Vuelve a probar Desbloqueo facial"
"Para guardar nuevos datos faciales, borra otros antiguos."
@@ -683,8 +681,6 @@
"Usar Desbloqueo facial o Bloqueo de pantalla"
"Usa tu cara para continuar"
"Usa tu cara o tu bloqueo de pantalla para continuar"
-
-
"Se ha producido un error. Inténtalo de nuevo."
"Icono cara"
"leer la configuración de sincronización"
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index e79cacba10eb..becabdc8e4cb 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -663,8 +663,6 @@
"Teie näomudelit ei saa luua. Proovige uuesti."
"Tuvastati tumedad prillid. Teie nägu peab olema täielikult nähtaval."
"Tuvastati nägu kattev ese. Teie nägu peab olema täielikult nähtaval."
-
-
"Nägu ei saa kinnitada. Riistvara pole saadaval."
"Proovige näoga avamist uuesti"
"Uue näo andmeid ei saa salvestada. Kustutage enne vanad."
@@ -682,8 +680,6 @@
"Näoga avamise või ekraaniluku kasutamine"
"Jätkamiseks kasutage oma nägu"
"Jätkamiseks kasutage oma nägu või ekraanilukku"
-
-
"Midagi läks valesti. Proovige uuesti."
"Näoikoon"
"loe sünkroonimisseadeid"
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 954c683ff3e7..337ef5cef1f4 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -663,8 +663,6 @@
"Ezin da sortu aurpegi-eredua. Saiatu berriro."
"Betaurreko ilunak hauteman dira. Aurpegi osoak egon behar du ikusgai."
"Maskara bat hauteman da. Aurpegi osoak egon behar du ikusgai."
-
-
"Ezin da egiaztatu aurpegia. Hardwarea ez dago erabilgarri."
"Saiatu berriro aurpegi bidez desblokeatzen"
"Ezin dira gorde aurpegiaren datu berriak. Ezabatu zaharrak."
@@ -682,8 +680,6 @@
"Erabili aurpegia edo pantailaren blokeoa"
"Aurrera egiteko, erabili aurpegia"
"Aurrera egiteko, erabili aurpegia edo pantailaren blokeoa"
-
-
"Arazo bat izan da. Saiatu berriro."
"Aurpegiaren ikonoa"
"irakurri sinkronizazio-ezarpenak"
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 424efe1edf6b..ae214c4d098f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -663,8 +663,6 @@
"مدل چهره ایجاد نشد. دوباره امتحان کنید."
"عینک تیره شناسایی شد. چهرهتان باید کاملاً نمایان باشد."
"پوشش صورت شناسایی شد. چهرهتان باید کاملاً نمایان باشد."
-
-
"چهره تأیید نشد. سختافزار در دسترس نیست."
"«قفلگشایی با چهره» را دوباره امتحان کنید"
"داده چهره جدید ذخیره نشد. اول داده چهره قدیمی را حذف کنید."
@@ -682,8 +680,6 @@
"استفاده از قفل صفحه یا چهره"
"برای ادامه، از چهرهتان استفاده کنید"
"برای ادامه، از تشخیص چهره یا قفل صفحه استفاده کنید"
-
-
"مشکلی پیش آمد. دوباره امتحان کنید."
"نماد چهره"
"خواندن تنظیمات همگامسازی"
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3f2b4ceb8d3e..0a09d9cdc15c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -663,8 +663,6 @@
"Kasvomallia ei voi luoda. Yritä uudelleen."
"Tummat lasit havaittu. Kasvojen täytyy näkyä kokonaan."
"Kasvot peittävä asia havaittu. Kasvojen täytyy näkyä kokonaan."
-
-
"Kasvoja ei voi vahvistaa. Laitteisto ei käytettäv."
"Yritä käyttää kasvojentunnistusavausta uudelleen"
"Uutta kasvodataa ei voi tallentaa. Poista ensin vanhaa."
@@ -682,8 +680,6 @@
"Käytä kasvojentunnistusavausta tai näytön lukitusta"
"Jatka kasvojesi avulla"
"Jatka kasvojentunnistuksen tai näytön lukituksen avulla"
-
-
"Jotain meni vikaan. Yritä uudelleen."
"Kasvokuvake"
"lue synkronointiasetuksia"
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 067388d7798a..df7a298a4f42 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -664,8 +664,6 @@
"Impossible de créer votre modèle facial. Réessayez."
"Lunettes sombres détectées. Votre visage doit être entièrement visible."
"Couvre-visage détecté. Votre visage doit être entièrement visible."
-
-
"Imposs. de vérif. visage. Matériel non accessible."
"Réessayez déverrouillage reconnaissance faciale"
"Impossible de stocker de nouveaux visages. Supprimez-en un."
@@ -683,8 +681,6 @@
"Utiliser la reconnaissance faciale ou le verrouillage de l\'écran"
"Utilisez votre visage pour continuer"
"Utilisez votre visage ou le verrouillage de l\'écran pour continuer"
-
-
"Un problème est survenu. Réessayez."
"Icône visage"
"lire les paramètres de synchronisation"
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 204c658c0b63..7e9f088c7fab 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -664,8 +664,6 @@
"Impossible de créer votre empreinte faciale. Réessayez."
"Lunettes sombres détectées. Votre visage doit être entièrement visible."
"Masque détecté. Votre visage doit être entièrement visible."
-
-
"Imposs. valider visage. Matériel non disponible."
"Réessayez d\'utiliser le déverrouillage facial"
"Impossible stocker nouv. visages. Veuillez en supprimer un."
@@ -683,8 +681,6 @@
"Utiliser déverrouillage par authent. faciale ou verrouillage écran"
"Utilisez la reconnaissance faciale pour continuer"
"Utilisez la reconnaissance faciale ou le verrouillage de l\'écran pour continuer"
-
-
"Un problème est survenu. Réessayez."
"Icône visage"
"lire les paramètres de synchronisation"
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index b092453bebcf..4fbf81cf21e1 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -663,8 +663,6 @@
"Non se puido crear o modelo facial. Téntao de novo."
"Detectáronse lentes escuras. A cara debe poder verse por completo."
"Detectouse unha máscara. A cara debe poder verse por completo."
-
-
"Sen verificar a cara. Hardware non dispoñible."
"Tenta utilizar o desbloqueo facial de novo"
"Para gardar novos datos faciais, elimina os antigos."
@@ -682,8 +680,6 @@
"Utilizar desbloqueo facial ou credencial do dispositivo"
"Usa a cara para continuar"
"Para continuar, utiliza o desbloqueo facial ou a credencial do dispositivo"
-
-
"Produciuse un erro. Téntao de novo."
"Icona cara"
"ler a configuración de vinculación"
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fa3784fa385a..ce903d8f6992 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -663,8 +663,6 @@
"તમારા ચહેરાનું મૉડલ ન બનાવી શકાય. ફરી પ્રયાસ કરો."
"કાળા ચશ્માંની ભાળ મળી. તમારો આખો ચહેરો દેખાવો આવશ્યક છે."
"ચહેરો ઢંકાયેલો હોવાની ભાળ મળી. તમારો આખો ચહેરો દેખાવો આવશ્યક છે."
-
-
"ચહેરો ચકાસી શકાતો નથી. હાર્ડવેર ઉપલબ્ધ નથી."
"ફેસ અનલૉકને ફરી અજમાવો"
"ચહેરાનો નવો ડેટા સ્ટોર કરી શકતાં નથી. પહેલા જૂનો ડિલીટ કરો."
@@ -682,8 +680,6 @@
"ફેસ લૉક અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"
"આગળ વધવા માટે તમારા ચહેરાનો ઉપયોગ કરો"
"ચાલુ રાખવા માટે તમારા ફેસ લૉક અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"
-
-
"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."
"ચહેરા આઇકન"
"સિંક સેટિંગ વાંચો"
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index cb0e30daba2e..c4b2570921fe 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -663,8 +663,6 @@
"चेहरे का माॅडल नहीं बन सका. फिर से कोशिश करें."
"आपने गहरे रंग का चश्मा पहना है. आपका पूरा चेहरा दिखना चाहिए."
"चेहरा ढका हुआ है. आपका पूरा चेहरा दिखना चाहिए."
-
-
"चेहरा नहीं पहचान पा रहे. हार्डवेयर उपलब्ध नहीं है."
"फ़ेस अनलॉक की सुविधा फिर से आज़माएं"
"चेहरे का नया डेटा सेव नहीं हो सकता. कोई पुराना डेटा मिटाएं."
@@ -682,8 +680,6 @@
"\'फ़ेस अनलॉक\' या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"
"जारी रखने के लिए, अपने चेहरे की मदद से पुष्टि करें"
"जारी रखने के लिए, अपना चेहरा दिखाकर या स्क्रीन लॉक क्रेडेंशियल डालकर पुष्टि करें"
-
-
"कोई गड़बड़ी हुई. फिर से कोशिश करें."
"चेहरे का आइकॉन"
"समन्वयन सेटिंग पढ़ें"
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index fb95a1f1acca..a63b56b08376 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -664,8 +664,6 @@
"Izrada modela lica nije uspjela. Pokušajte ponovo."
"Otkrivene su tamne naočale. Vaše lice mora biti potpuno vidljivo."
"Otkriveno je prekrivanje lica. Vaše lice mora biti potpuno vidljivo."
-
-
"Lice nije potvrđeno. Hardver nije dostupan."
"Ponovo pokušajte otključavanje licem"
"Podaci o novom licu nisu pohranjeni. Izbrišite neko staro."
@@ -683,8 +681,6 @@
"Upotreba otključavanja licem ili zaključavanja zaslona"
"Autentificirajte se licem da biste nastavili"
"Za nastavak se identificirajte licem ili vjerodajnicom zaključavanja zaslona"
-
-
"Nešto nije u redu. Pokušajte ponovo."
"Ikona lica"
"čitanje postavki sinkronizacije"
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6c700dd1179c..ee0f0ed59aa8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -663,8 +663,6 @@
"Nem lehet létrehozni az arcmodellt. Próbálja újra."
"Sötét szemüveget észlelt a rendszer. Arcának teljesen láthatónak kell lennie."
"Valami eltakarja az arcát. Arcának teljesen láthatónak kell lennie."
-
-
"Sikertelen arcellenőrzés. A hardver nem érhető el."
"Próbálja újra az Arcalapú feloldást"
"Nem tárolhatók újabb arcadatok. Törölje valamelyik arcot."
@@ -682,8 +680,6 @@
"A folytatás arcalapú feloldással vagy képernyőzárral lehetséges"
"A folytatáshoz használja az arcalapú feloldást"
"A folytatás arcalapú feloldással vagy a képernyőzár feloldásával lehetséges"
-
-
"Hiba történt. Próbálja újra."
"Arcikon"
"szinkronizálási beállítások olvasása"
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c335648726eb..5c86cd73c233 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -663,8 +663,6 @@
"Չհաջողվեց ստեղծել ձեր դեմքի մոդելը։ Նորից փորձեք։"
"Հանեք ակնոցը։ Ձեր դեմքը պետք է ամբողջովին տեսանելի լինի։"
"Դեմքի մի մասը ծածկված է։ Ձեր դեմքը պետք է ամբողջովին տեսանելի լինի։"
-
-
"Չհաջողվեց հաստատել դեմքը։ Սարքն անհասանելի է:"
"Նորից փորձեք դեմքով ապակողպումը"
"Չհաջողվեց պահել նոր դեմքը։ Ջնջեք հին տարբերակը։"
@@ -682,8 +680,6 @@
"Օգտագործել դեմքով ապակողպում կամ էկրանի կողպում"
"Շարունակելու համար օգտագործեք դեմքի նույնականացումը"
"Շարունակելու համար օգտագործեք ձեր դեմքը կամ էկրանի կողպումը"
-
-
"Սխալ առաջացավ։ Նորից փորձեք։"
"Դեմքի պատկերակ"
"կարդալ համաժամացման կարգավորումները"
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 405717cbb85f..9c49a6ccd8ba 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -663,8 +663,6 @@
"Tidak dapat membuat model wajah Anda. Coba lagi."
"Kacamata hitam terdeteksi. Wajah Anda harus terlihat sepenuhnya."
"Penutup wajah terdeteksi. Wajah Anda harus terlihat sepenuhnya."
-
-
"Tidak dapat memverifikasi wajah. Hardware tidak tersedia."
"Coba Face Unlock lagi"
"Tidak dapat menyimpan data wajah. Hapus dahulu data lama."
@@ -682,8 +680,6 @@
"Gunakan face lock atau kunci layar"
"Gunakan wajah untuk melanjutkan"
"Gunakan face lock atau kunci layar untuk melanjutkan"
-
-
"Terjadi error. Coba lagi."
"Ikon wajah"
"baca setelan sinkronisasi"
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 743a21511e9d..7bc698b2ecf9 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -663,8 +663,6 @@
"Ekki tekst að búa til andlitslíkan. Reyndu aftur."
"Dökk gleraugu greindust. Allt andlitið á þér þarf að sjást."
"Eitthvað er fyrir andlitinu. Allt andlitið á þér þarf að sjást."
-
-
"Andlit ekki staðfest. Vélbúnaður er ekki tiltækur."
"Prófaðu andlitskenni aftur."
"Ekki er hægt að vista ný andlitsgögn. Eyddu gömlu fyrst."
@@ -682,8 +680,6 @@
"Nota andlit eða skjálás"
"Notaðu andlitið þitt til að halda áfram"
"Notaðu andlitið eða skjálás til að halda áfram"
-
-
"Eitthvað fór úrskeiðis. Reyndu aftur."
"Andlitstákn"
"lesa samstillingar"
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0e32d331241c..2e3da3c8b8d6 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -664,8 +664,6 @@
"Impossibile creare il modello del volto. Riprova."
"Sono stati rilevati occhiali scuri. Il tuo volto deve essere visibile per intero."
"È stata rilevata una mascherina. Il tuo volto deve essere visibile per intero."
-
-
"Imposs. verificare volto. Hardware non disponibile."
"Riprova lo sblocco con il volto"
"Imposs. salvare dati nuovi volti. Elimina un volto vecchio."
@@ -683,8 +681,6 @@
"Usa lo sblocco con il volto o il blocco schermo"
"Usa il tuo volto per continuare"
"Per continuare devi usare il tuo volto o il tuo blocco schermo"
-
-
"Si è verificato un errore. Riprova."
"Icona volto"
"lettura impostazioni di sincronizz."
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 57176a60fc80..181b004bfa9b 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -665,8 +665,6 @@
"לא ניתן ליצור את התבנית לזיהוי הפנים. יש לנסות שוב."
"זוהו משקפיים כהים. הפנים שלך חייבות להיות גלויות לגמרי."
"זוהה כיסוי על הפנים. הפנים שלך חייבות להיות גלויות לגמרי."
-
-
"לא ניתן לאמת את הפנים. החומרה לא זמינה."
"יש לנסות שוב את הפתיחה ע\"י זיהוי הפנים"
"לא ניתן לאחסן נתוני פנים חדשים. תחילה יש למחוק את הנתונים הישנים."
@@ -684,8 +682,6 @@
"שימוש בזיהוי פנים או בנעילת מסך"
"יש להשתמש באימות פנים כדי להמשיך"
"יש להשתמש בזיהוי הפנים או בנעילת המסך כדי להמשיך"
-
-
"משהו השתבש. עליך לנסות שוב."
"סמל הפנים"
"קריאת הגדרות הסנכרון"
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index c48d37cc8d50..c7e39eedf1b8 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -663,8 +663,6 @@
"顔モデルを作成できません。もう一度お試しください。"
"サングラスが検出されました。顔が完全に写るようにしてください。"
"マスクが検出されました。顔が完全に写るようにしてください。"
-
-
"顔を確認できません。ハードウェアを利用できません。"
"顔認証をもう一度お試しください"
"新しい顔データを保存できません。古いデータを削除してください。"
@@ -682,8 +680,6 @@
"顔認証または画面ロックの使用"
"続行するには顔認証を使用してください"
"続行するには、顔認証または画面ロックを使用してください"
-
-
"エラーが発生しました。もう一度お試しください。"
"顔アイコン"
"同期設定の読み取り"
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 9cc6ae48df0b..832fe0055c57 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -663,8 +663,6 @@
"თქვენი სახის მოდელი ვერ იქმნება. ცადეთ ხელახლა."
"აღმოჩენილია მუქი სათვალე. თქვენი სახე მთლიანად უნდა ჩანდეს."
"აღმოჩენილია სახის დაფარვა. თქვენი სახე მთლიანად უნდა ჩანდეს."
-
-
"სახე ვერ დასტურდება. აპარატი მიუწვდომელია."
"ხელახლა ცადეთ სახით განბლოკვა"
"სახის ახალი მონაცემები ვერ ინახება. ჯერ ძველი წაშალეთ."
@@ -682,8 +680,6 @@
"გამოიყენეთ სახით ან ეკრანის დაბლოკვა"
"გასაგრძელებლად გამოიყენეთ თქვენი სახე"
"გასაგრძელებლად გამოიყენეთ თქვენი სახე ან ეკრანის განბლოკვის ნიმუში"
-
-
"რაღაც შეცდომა მოხდა. ცადეთ ხელახლა."
"სახის ხატულა"
"სინქრონიზაციის პარამეტრების წაკითხვა"
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 4c5fe51d548b..12fc46a17d82 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -663,8 +663,6 @@
"Бет үлгісі жасалмады. Қайталап көріңіз."
"Қою түсті көзілдірік анықталды. Бетіңіз толық көрініп тұруы керек."
"Бетперде анықталды. Бетіңіз толық көрініп тұруы керек."
-
-
"Бетті тану мүмкін емес. Жабдық қолжетімді емес."
"Бет тану функциясын қайта қолданып көріңіз."
"Жаңа бетті сақтау мүмкін емес. Алдымен ескісін жойыңыз."
@@ -682,8 +680,6 @@
"Face Lock функциясын немесе экран құлпын пайдалану"
"Жалғастыру үшін бетіңізді көрсетіңіз."
"Жалғастыру үшін бетті анықтау функциясын немесе экран құлпын пайдаланыңыз."
-
-
"Бірдеңе дұрыс болмады. Қайталап көріңіз."
"Бет белгішесі"
"синх параметрлерін оқу"
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index eb8f757200f5..29f3d6dd0680 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -663,8 +663,6 @@
"មិនអាចបង្កើតគំរូមុខរបស់អ្នកបានទេ។ សូមព្យាយាមម្ដងទៀត។"
"បានរកឃើញវ៉ែនតាខ្មៅ។ មុខរបស់អ្នកត្រូវតែអាចមើលឃើញពេញលេញ។"
"បានរកឃើញគ្រឿងពាក់លើមុខ។ មុខរបស់អ្នកត្រូវតែអាចមើលឃើញពេញលេញ។"
-
-
"មិនអាចផ្ទៀងផ្ទាត់មុខបានទេ។ មិនមានហាតវែរទេ។"
"សាកល្បងដោះសោតាមទម្រង់មុខម្ដងទៀត"
"មិនអាចផ្ទុកទិន្នន័យទម្រង់មុខថ្មីបានទេ។ សូមលុបទិន្នន័យទម្រង់មុខចាស់ជាមុនសិន។"
@@ -682,8 +680,6 @@
"ប្រើមុខ ឬការចាក់សោអេក្រង់"
"ប្រើមុខរបស់អ្នក ដើម្បីបន្ត"
"ប្រើការចាក់សោអេក្រង់ ឬមុខរបស់អ្នក ដើម្បីបន្ត"
-
-
"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"
"រូបផ្ទៃមុខ"
"អានការកំណត់ធ្វើសមកាលកម្ម"
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 0c7d4b176247..a69a00eaaefc 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -663,8 +663,6 @@
"ಫೇಸ್ ಮಾಡೆಲ್ ರಚಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."
"ಕಪ್ಪು ಕನ್ನಡಕ ಪತ್ತೆಯಾಗಿದೆ. ನಿಮ್ಮ ಮುಖವು ಸಂಪೂರ್ಣವಾಗಿ ಗೋಚರಿಸಬೇಕು."
"ಮುಖವಾಡ ಪತ್ತೆಯಾಗಿದೆ. ನಿಮ್ಮ ಮುಖವು ಸಂಪೂರ್ಣವಾಗಿ ಗೋಚರಿಸಬೇಕು."
-
-
"ಮುಖ ದೃಢೀಕರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಹಾರ್ಡ್ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."
"ಫೇಸ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"
"ಹೊಸ ಮುಖ ಡೇಟಾ ಸಂಗ್ರಹಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಮೊದಲು ಹಳೆಯದನ್ನು ಅಳಿಸಿ"
@@ -682,8 +680,6 @@
"ಫೇಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"
"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಮುಖವನ್ನು ಬಳಸಿ"
"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಮುಖ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"
-
-
"ಏನೋ ತಪ್ಪಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."
"ಮುಖದ ಐಕಾನ್"
"ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ರೀಡ್ ಮಾಡು"
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 82ab2629cb8a..e68611b04f66 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -663,8 +663,6 @@
"얼굴 모델을 만들 수 없습니다. 다시 시도해 주세요."
"선글라스가 감지되었습니다. 전체 얼굴이 보여야 합니다."
"마스크가 감지되었습니다. 전체 얼굴이 보여야 합니다."
-
-
"얼굴을 확인할 수 없습니다. 하드웨어를 사용할 수 없습니다."
"얼굴 인식 잠금 해제를 다시 시도해 주세요."
"새 얼굴 데이터를 저장할 수 없습니다. 먼저 기존 얼굴 데이터를 삭제하세요."
@@ -682,8 +680,6 @@
"얼굴 또는 화면 잠금 사용"
"계속하려면 얼굴로 인증하세요"
"계속하려면 얼굴 또는 화면 잠금을 사용하세요"
-
-
"문제가 발생했습니다. 다시 시도해 보세요."
"얼굴 아이콘"
"동기화 설정 읽기"
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index cdbad1854918..5a37f52d9244 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -663,8 +663,6 @@
"Жүзүңүздүн үлгүсү түзүлгөн жок. Кайталаңыз."
"Кара көз айнек кийгенге болбойт. Жүзүңүз толук көрүнүшү керек."
"Жүзүңүз жабылып калды. Ал толук көрүнүшү керек."
-
-
"Жүз ырасталбай жатат. Аппараттык камсыздоо жеткиликсиз."
"Жүзүнөн таанып ачуу функциясын кайрадан колдонуңуз"
"Жаңы жүздү сактоо мүмкүн эмес. Адегенде эскисин өчүрүңүз."
@@ -682,8 +680,6 @@
"Жүзүнөн таанып ачууну же экрандын кулпусун колдонуу"
"Улантуу үчүн жүзүңүздү көрсөтүңүз"
"Улантуу үчүн жүзүңүздү же экрандын кулпусун колдонуңуз"
-
-
"Бир жерден ката кетти. Кайра аракет кылыңыз."
"Жүздүн сүрөтчөсү"
"шайкештирүү жөндөөлөрүн окуу"
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 81ec5b7054c0..a62d11606caa 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -663,8 +663,6 @@
"ບໍ່ສາມາດສ້າງຮູບແບບໃບໜ້າຂອງທ່ານໄດ້. ກະລຸນາລອງໃໝ່."
"ກວດພົບແວ່ນຕາດຳ. ໃບໜ້າຂອງທ່ານຕ້ອງສະແດງໃຫ້ເຫັນໝົດ."
"ກວດພົບການປົກປິດໃບໜ້າ. ໃບໜ້າຂອງທ່ານຕ້ອງສະແດງໃຫ້ເຫັນໝົດ."
-
-
"ບໍ່ສາມາດຢັ້ງຢືນໃບໜ້າໄດ້. ບໍ່ມີຮາດແວໃຫ້ໃຊ້."
"ກະລຸນາລອງປົດລັອກດ້ວຍໜ້າອີກເທື່ອໜຶ່ງ"
"ບໍ່ສາມາດບັນທຶກຂໍ້ມູນໃບໜ້າໃໝ່ໄດ້. ກະລຸນາລຶບຂໍ້ມູນເກົ່າອອກກ່ອນ."
@@ -682,8 +680,6 @@
"ໃຊ້ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍ"
"ໃຊ້ໜ້າທ່ານເພື່ອສືບຕໍ່"
"ໃຊ້ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"
-
-
"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ກະລຸນາລອງໃໝ່."
"ໄອຄອນໃບໜ້າ"
"ອ່ານການຕັ້ງຄ່າຊິ້ງຂໍ້ມູນ"
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 004a0a8fbb7a..d63fa55eb0ac 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -665,8 +665,6 @@
"Nepavyko sukurti veido modelio. Band. dar kartą."
"Aptikti akiniai nuo saulės. Visas veidas turi būti matomas."
"Aptikta veido kaukė. Visas veidas turi būti matomas."
-
-
"Nepavyko patv. veido. Aparatinė įranga negalima."
"Bandykite dar kartą naudoti atrakinimą pagal veidą"
"Nepavyko išs. naujų veido duomenų. Pirm. ištrinkite senus."
@@ -684,8 +682,6 @@
"Naudoti atrakinimą pagal veidą arba ekrano užraktą"
"Jei norite tęsti, naudokite atpažinimą pagal veidą"
"Jei norite tęsti, naudokite veido atpažinimo funkciją arba ekrano užraktą"
-
-
"Kažkas nepavyko. Bandykite dar kartą."
"Veido pkt."
"skaityti sinchronizavimo nustatymus"
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index ef1a95f616c4..51320747b484 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -664,8 +664,6 @@
"Nevar izveidot sejas modeli. Mēģiniet vēlreiz."
"Konstatētas tumšas brilles. Sejai ir jābūt pilnībā redzamai."
"Konstatēts sejas aizsegs. Sejai ir jābūt pilnībā redzamai."
-
-
"Nevar verificēt seju. Aparatūra nav pieejama."
"Vēlreiz mēģiniet veikt autorizāciju pēc sejas."
"Nevar saglabāt jaunās sejas datus. Dzēsiet kādu no vecajām."
@@ -683,8 +681,6 @@
"Autorizācijas pēc sejas vai ekrāna bloķēšanas metodes izmantošana"
"Lai turpinātu, veiciet autorizāciju pēc sejas"
"Izmantojiet autorizāciju pēc sejas vai ekrāna bloķēšanas opciju, lai turpinātu"
-
-
"Radās kļūda. Mēģiniet vēlreiz."
"Sejas ikona"
"lasīt sinhronizācijas iestatījumus"
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 667f5023fc79..5100a29fe64c 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -663,8 +663,6 @@
"Не може да создаде модел на лик. Обидете се пак."
"Носите темни очила. Лицето мора да ви се гледа целосно."
"Лицето е покриено. Лицето мора да ви се гледа целосно."
-
-
"Ликот не може да се потврди. Хардвер - недостапен."
"Пробајте „Отклучување со лик“ повторно"
"Не се зачуваа податоците за нов лик. Избришете го стариот."
@@ -682,8 +680,6 @@
"Користи лик или заклучување екран"
"Користете го вашиот лик за да продолжите"
"Користете отклучување со лик или заклучување екран за да продолжите"
-
-
"Нешто не е во ред. Обидете се повторно."
"Икона"
"чита поставки за синхронизација"
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 4bd200125a80..255b72774d3a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -663,8 +663,6 @@
"മുഖ മോഡൽ സൃഷ്ടിക്കാനാകില്ല. വീണ്ടും ശ്രമിക്കൂ."
"കറുത്ത കണ്ണട കണ്ടെത്തി. നിങ്ങളുടെ മുഖം പൂർണ്ണമായും ദൃശ്യമായിരിക്കണം."
"മുഖം മറച്ചിരിക്കുന്നതായി കണ്ടെത്തി. നിങ്ങളുടെ മുഖം പൂർണ്ണമായും ദൃശ്യമായിരിക്കണം."
-
-
"മുഖം പരിശോധിക്കാൻ കഴിയില്ല. ഹാർഡ്വെയർ ലഭ്യമല്ല."
"ഫെയ്സ് അൺലോക്ക് വീണ്ടും പരീക്ഷിച്ച് നോക്കൂ"
"പുതിയ മുഖ ഡാറ്റ സംഭരിക്കാനാകില്ല. ആദ്യം പഴയത് ഇല്ലാതാക്കുക."
@@ -682,8 +680,6 @@
"ഫെയ്സ് അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"
"തുടരാൻ നിങ്ങളുടെ മുഖം ഉപയോഗിക്കുക"
"തുടരാൻ നിങ്ങളുടെ മുഖം അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"
-
-
"എന്തോ കുഴപ്പമുണ്ടായി. വീണ്ടും ശ്രമിക്കുക."
"മുഖത്തിന്റെ ഐക്കൺ"
"സമന്വയ ക്രമീകരണങ്ങൾ റീഡുചെയ്യുക"
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 1b92252f2b47..c6de1844b3d5 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -663,8 +663,6 @@
"Нүүрний загвар үүсгэж чадсангүй. Дахин оролдоно уу."
"Хар шил илэрлээ. Таны нүүр бүтэн харагдах ёстой."
"Нүүрний халхавч илэрлээ. Таны нүүр бүтэн харагдах ёстой."
-
-
"Царайг бататгаж чадсангүй. Техник хангамж боломжгүй байна."
"Царайгаар түгжээ тайлахыг дахин оролдоно уу"
"Царайн шинэ өгөгдлийг хадгалж чадсангүй. Эхлээд хуучин өгөгдлийг устгана уу."
@@ -682,8 +680,6 @@
"Царайгаар түгжээ тайлах эсвэл дэлгэцийн түгжээ ашиглах"
"Үргэлжлүүлэхийн тулд царайгаа ашиглана уу"
"Үргэлжлүүлэхийн тулд царай эсвэл дэлгэцийн түгжээгээ ашиглана уу"
-
-
"Алдаа гарлаа. Дахин оролдоно уу."
"Царайны дүрс тэмдэг"
"синк тохиргоог унших"
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index fd7ce2ef9b06..d28c40206d9a 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -663,8 +663,6 @@
"फेस मॉडेल तयार करू शकत नाही. पुन्हा प्रयत्न करा."
"गडद चष्मा डिटेक्ट केला. तुमचा चेहरा पूर्णपणे दृश्यमान असणे आवश्यक आहे."
"चेहर्यावरील आच्छादन डिटेक्ट केले. तुमचा चेहरा पूर्णपणे दृश्यमान असणे आवश्यक आहे."
-
-
"चेहरा पडताळू शकत नाही. हार्डवेअर उपलब्ध नाही."
"फेस अनलॉक वापरण्याचा पुन्हा प्रयत्न करा"
"नवीन फेस डेटा स्टोअर करू शकत नाही. आधी जुना हटवा."
@@ -682,8 +680,6 @@
"फेस किंवा स्क्रीन लॉक वापरा"
"पुढे सुरू ठेवण्यासाठी तुमचा चेहरा वापरा"
"पुढे सुरू ठेवण्यासाठी तुमचा चेहरा किंवा स्क्रीन लॉक वापरा"
-
-
"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."
"चेहरा आयकन"
"सिंक सेटिंग्ज वाचा"
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5a623be45dbd..20fea67e090e 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -663,8 +663,6 @@
"Tidak dapat membuat model wajah anda. Cuba lagi."
"Cermin mata gelap dikesan. Wajah anda mesti terlihat sepenuhnya."
"Pelitup muka dikesan. Wajah anda mesti terlihat sepenuhnya."
-
-
"Tdk dpt sahkan wajah. Perkakasan tidak tersedia."
"Cuba Buka Kunci Wajah sekali lagi"
"Tdk dpt menyimpan data wajah baharu. Padamkan yg lama dahulu."
@@ -682,8 +680,6 @@
"Gunakan kunci wajah atau skrin"
"Gunakan wajah untuk teruskan"
"Gunakan wajah atau kunci skrin anda untuk meneruskan"
-
-
"Kesilapan telah berlaku. Cuba lagi."
"Ikon wajah"
"membaca tetapan penyegerakan"
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index abb274023b3b..71b6f1fa4b2b 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -663,8 +663,6 @@
"သင့်မျက်နှာနမူနာ ပြုလုပ်၍မရပါ။ ထပ်စမ်းကြည့်ပါ။"
"အရောင်ရင့်သောမျက်မှန် တွေ့သည်။ သင့်မျက်နှာကို အပြည့်အဝ မြင်ရရန်လိုအပ်သည်။"
"မျက်နှာဖုံး တွေ့သည်။ သင့်မျက်နှာကို အပြည့်အဝ မြင်ရရန်လိုအပ်သည်။"
-
-
"မျက်နှာကို အတည်ပြု၍ မရပါ။ ဟာ့ဒ်ဝဲ မရနိုင်ပါ။"
"မျက်နှာပြ လော့ခ်ဖွင့်ခြင်းကို ထပ်စမ်းကြည့်ပါ"
"မျက်နှာဒေတာအသစ် သိမ်း၍မရပါ။ အဟောင်းကို အရင်ဖျက်ပါ။"
@@ -682,8 +680,6 @@
"မျက်နှာမှတ်သော့ဖွင့်ခြင်း (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"
"ရှေ့ဆက်ရန် သင့်မျက်နှာကို သုံးပါ"
"ရှေ့ဆက်ရန် သင်၏ မျက်နှာ (သို့) ဖန်သားပြင်လော့ခ်ကို သုံးပါ"
-
-
"တစ်ခုခုမှားသွားသည်။ ထပ်စမ်းကြည့်ပါ။"
"မျက်နှာသင်္ကေတ"
"ထပ်တူပြုအဆင်အပြင်အားဖတ်ခြင်း"
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index abc586770796..aaa161dc5839 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -663,8 +663,6 @@
"Kan ikke lage ansiktsmodell. Prøv på nytt."
"Mørke briller er registrert. Ansiktet må være helt synlig."
"Ansiktsdekke er registrert. Ansiktet må være helt synlig."
-
-
"Kan ikke bekrefte ansikt. Utilgjengelig maskinvare."
"Prøv ansiktslås igjen"
"Kan ikke lagre nye ansiktsdata. Slett gamle data først."
@@ -682,8 +680,6 @@
"Bruk ansikts- eller skjermlås"
"Bruk ansiktet for å fortsette"
"Bruk ansikts- eller skjermlåsen for å fortsette"
-
-
"Noe gikk galt. Prøv på nytt."
"Ansiktikon"
"lese synkroniseringsinnstillinger"
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 60b0eeab1645..31344797169f 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -663,8 +663,6 @@
"तपाईंको फेस मोडेल सिर्जना गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"
"कालो चस्मा लगाइएको पाइयो। तपाईंको अनुहार पूरै देखिनु पर्छ।"
"अनुहार छोपिएको पाइयो। तपाईंको अनुहार पूरै देखिनु पर्छ।"
-
-
"अनुहार पुष्टि गर्न सकिएन। हार्डवेयर उपलब्ध छैन।"
"फेरि फेस अनलक प्रयोग गरी हेर्नुहोस्"
"अनुहारसम्बन्धी नयाँ डेटा भण्डारण गर्न सकिएन। पहिले कुनै पुरानो डेटा मेटाउनुहोस्।"
@@ -682,8 +680,6 @@
"फेस अनलक वा स्क्रिन लक प्रयोग गर्नुहोस्"
"जारी राख्न आफ्नो अनुहारको सहायताले पुष्टि गर्नुहोस्"
"जारी राख्न आफ्नो फेस वा स्क्रिन लक प्रयोग गरी पुष्टि गर्नुहोस्"
-
-
"केही चिज गडबड भयो। फेरि प्रयास गर्नुहोस्।"
"अनुहारको आइकन"
"समीकरण सेटिङहरू पढ्नुहोस्"
diff --git a/core/res/res/values-night/bootleg_colors.xml b/core/res/res/values-night/bootleg_colors.xml
new file mode 100644
index 000000000000..add64d966d16
--- /dev/null
+++ b/core/res/res/values-night/bootleg_colors.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ @*android:color/system_accent3_100
+
+
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 7cfdba7a65be..cb682118f6e0 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -52,7 +52,7 @@ easier.
diff --git a/core/res/res/values-night/values.xml b/core/res/res/values-night/values.xml
index 1571fab66a5b..0683c20a4a4c 100644
--- a/core/res/res/values-night/values.xml
+++ b/core/res/res/values-night/values.xml
@@ -22,6 +22,7 @@
- @color/secondary_device_default_settings
- @color/accent_device_default_dark
- @color/error_color_device_default_dark
+ - @color/surface_header_dark_sysui
- ?attr/textColorPrimary
- @style/Theme.DeviceDefault.Dialog.Alert
- false
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 251a53a85765..eec2d4acc154 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -663,8 +663,6 @@
"Kan gezichtsmodel niet maken. Probeer het opnieuw."
"Donkere bril waargenomen. Je gezicht moet geheel zichtbaar zijn."
"Gezichtsbedekking waargenomen. Je gezicht moet geheel zichtbaar zijn."
-
-
"Kan gezicht niet verifiëren. Hardware niet beschikbaar."
"Ontgrendel opnieuw via gezichtsherkenning"
"Kan nieuwe gezichten niet opslaan. Verwijder eerst een oude."
@@ -682,8 +680,6 @@
"Gezicht of schermgrendeling gebruiken"
"Gebruik je gezicht om door te gaan"
"Gebruik je gezicht of schermvergrendeling om door te gaan"
-
-
"Er is iets misgegaan. Probeer het opnieuw."
"Gezichtspictogram"
"synchronisatie-instellingen lezen"
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 26bfeb4acec2..8929cde9f088 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -663,8 +663,6 @@
"ଫେସର ମଡେଲ ତିଆରି କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କର।"
"କଳା ଚଷମା ଚିହ୍ନଟ କରାଯାଇଛି। ଆପଣଙ୍କ ଫେସ ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଦେଖାଯିବା ଆବଶ୍ଯକ।"
"ଫେସରେ କଭରିଂ ଚିହ୍ନଟ କରାଯାଇଛି। ଆପଣଙ୍କ ଫେସ ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଦେଖାଯିବା ଆବଶ୍ଯକ।"
-
-
"ମୁହଁ ଚିହ୍ନଟ କରିପାରିଲା ନାହିଁ। ହାର୍ଡୱେୟାର୍ ଉପଲବ୍ଧ ନାହିଁ।"
"ଫେସ୍ ଅନଲକ୍ ପୁଣି ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"
"ନୂଆ ମୁହଁ ଡାଟା ଷ୍ଟୋର୍ ହେବ ନାହିଁ। ପ୍ରଥମେ ପୁରୁଣାକୁ ଡିଲିଟ୍ କରନ୍ତୁ।"
@@ -682,8 +680,6 @@
"ଫେସ୍ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"
"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଚେହେରା ବ୍ୟବହାର କରନ୍ତୁ"
"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଚେହେରା କିମ୍ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"
-
-
"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"
"ଫେସ୍ ଆଇକନ୍"
"ସିଙ୍କ ସେଟିଙ୍ଗକୁ ପଢ଼ନ୍ତୁ"
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index b61b0febd33d..62e3e5bbcc44 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -663,8 +663,6 @@
"ਤੁਹਾਡੇ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਨਹੀਂ ਬਣਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"
"ਧੁੱਪ ਦੀਆਂ ਐਨਕਾਂ ਦਾ ਪਤਾ ਲੱਗਾ। ਤੁਹਾਡਾ ਪੂਰਾ ਚਿਹਰਾ ਦਿਸਣਾ ਲਾਜ਼ਮੀ ਹੈ।"
"ਚਿਹਰਾ ਢੱਕਿਆ ਹੋਣ ਦਾ ਪਤਾ ਲੱਗਾ। ਤੁਹਾਡਾ ਪੂਰਾ ਚਿਹਰਾ ਦਿਸਣਾ ਲਾਜ਼ਮੀ ਹੈ।"
-
-
"ਚਿਹਰੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਹੋ ਸਕੀ। ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ।"
"ਫ਼ੇਸ ਅਣਲਾਕ ਦੁਬਾਰਾ ਵਰਤ ਕੇ ਦੇਖੋ"
"ਨਵਾਂ ਚਿਹਰਾ ਡਾਟਾ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਪਹਿਲਾਂ ਪੁਰਾਣਾ ਹਟਾਓ।"
@@ -682,8 +680,6 @@
"ਫ਼ੇਸ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"
"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣੇ ਚਿਹਰੇ ਦੀ ਵਰਤੋਂ ਕਰੋ"
"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਚਿਹਰਾ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ"
-
-
"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"
"ਚਿਹਰਾ ਪ੍ਰਤੀਕ"
"ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹੋ"
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7193eb7cb3ad..1be1d374d5ae 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -665,8 +665,6 @@
"Nie można utworzyć modelu twarzy. Spróbuj ponownie."
"Wykryto ciemne okulary. Twarz musi być widoczna w całości."
"Wykryto zasłonę twarzy. Twarz musi być widoczna w całości."
-
-
"Nie można zweryfikować twarzy. Sprzęt niedostępny."
"Spróbuj ponownie użyć rozpoznawania twarzy"
"Nie można przechowywać nowych danych twarzy. Usuń stare."
@@ -684,8 +682,6 @@
"Używaj rozpoznawania twarzy lub blokady ekranu"
"Użyj skanu twarzy, aby kontynuować"
"Aby kontynuować, użyj rozpoznawania twarzy lub blokady ekranu"
-
-
"Coś poszło nie tak. Spróbuj ponownie."
"Ikona twarzy"
"czytanie ustawień synchronizacji"
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index c1c0d5440304..8fc4c480bb7c 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -664,8 +664,6 @@
"Falha ao criar o modelo de rosto. Tente de novo."
"Óculos escuros detectados. Seu rosto precisa estar completamente visível."
"Máscara detectada. Seu rosto precisa estar completamente visível."
-
-
"Impossível verificar rosto. Hardware indisponível."
"Tente usar o Desbloqueio facial novamente"
"Não é possível salvar dados faciais. Exclua dados antigos."
@@ -683,8 +681,6 @@
"Usar reconhecimento facial ou bloqueio de tela"
"Use seu rosto para continuar"
"Use seu rosto ou o bloqueio de tela para continuar"
-
-
"Algo deu errado. Tente de novo."
"Ícone facial"
"ler as configurações de sincronização"
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1fe6e1c2c3af..ddb927841d1e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -664,8 +664,6 @@
"Não é possível criar o seu modelo de rosto. Tente novamente."
"Óculos escuros detetados. O seu rosto tem de estar completamente visível."
"Cobertura facial detetada. O seu rosto tem de estar completamente visível."
-
-
"Não pode validar o rosto. Hardware não disponível."
"Experimente o Desbloqueio facial novamente"
"Não pode guardar novos dados de rostos. Elimine um antigo."
@@ -683,8 +681,6 @@
"Utilizar o bloqueio através do rosto ou de ecrã"
"Utilize o rosto para continuar"
"Utilize o rosto ou o bloqueio de ecrã para continuar"
-
-
"Algo correu mal. Tente novamente."
"Ícone de rosto"
"ler definições de sincronização"
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c1c0d5440304..8fc4c480bb7c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -664,8 +664,6 @@
"Falha ao criar o modelo de rosto. Tente de novo."
"Óculos escuros detectados. Seu rosto precisa estar completamente visível."
"Máscara detectada. Seu rosto precisa estar completamente visível."
-
-
"Impossível verificar rosto. Hardware indisponível."
"Tente usar o Desbloqueio facial novamente"
"Não é possível salvar dados faciais. Exclua dados antigos."
@@ -683,8 +681,6 @@
"Usar reconhecimento facial ou bloqueio de tela"
"Use seu rosto para continuar"
"Use seu rosto ou o bloqueio de tela para continuar"
-
-
"Algo deu errado. Tente de novo."
"Ícone facial"
"ler as configurações de sincronização"
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 129f8fe68d88..2070a0ff7ef8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -664,8 +664,6 @@
"Nu se poate crea modelul facial. Reîncearcă."
"S-au detectat ochelari de culoare închisă. Chipul trebuie să fie vizibil în totalitate."
"S-a detectat un articol care acoperă chipul. Chipul trebuie să fie vizibil în totalitate."
-
-
"Nu se poate confirma fața. Hardware-ul nu este disponibil."
"Încearcă din nou Deblocarea facială"
"Nu se pot stoca date faciale noi. Șterge întâi unele vechi."
@@ -683,8 +681,6 @@
"Folosește deblocarea facială sau ecranul de blocare"
"Folosește-ți chipul pentru a continua"
"Folosește-ți chipul sau blocarea ecranului pentru a continua"
-
-
"A apărut o eroare. Încearcă din nou."
"Pictograma chip"
"să citească setări sincronizare"
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d01e430efd84..a99d36c20e89 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -665,8 +665,6 @@
"Невозможно создать модель лица. Повторите попытку."
"Обнаружены темные очки. Лицо должно быть полностью видно"
"Часть лица закрыта. Оно должно быть полностью видно."
-
-
"Не удалось распознать лицо. Сканер недоступен."
"Попробуйте воспользоваться фейсконтролем ещё раз."
"Недостаточно места. Удалите старые данные для распознавания."
@@ -684,8 +682,6 @@
"Использовать фейсконтроль или блокировку экрана"
"Чтобы продолжить, используйте функцию фейсконтроля."
"Чтобы продолжить, посмотрите на экран или используйте данные для разблокировки."
-
-
"Произошла ошибка. Повторите попытку."
"Значок лица"
"Просмотр настроек синхронизации"
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index ac0a3f6c7431..74b88ca8f488 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -663,8 +663,6 @@
"ඔබගේ මුහුණු ආකෘතිය තැනිය නොහැකිය. නැවත උත්සාහ කරන්න."
"අඳුරු කණ්ණාඩි අනාවරණය කර ගන්නා ලදි. ඔබගේ මුහුණ සම්පූර්ණයෙන් දෘශ්යමාන විය යුතුය."
"මුහුණු ආවරණය අනාවරණය කර ගන්නා ලදි. ඔබගේ මුහුණ සම්පූර්ණයෙන් දෘශ්යමාන විය යුතුය."
-
-
"මුහුණ සත්යාපනය කළ නොහැක. දෘඩාංගය නොමැත."
"මුහුණෙන් අගුළු හැරීම නැවත උත්සාහ කරන්න."
"නව මුහුණු දත්ත ගබඩා කළ නොහැක. පළමුව පැරණි එකක් මකන්න."
@@ -682,8 +680,6 @@
"මුහුණෙන් අගුළු හැරීම හෝ තිර අගුල භාවිත කරන්න"
"ඉදිරියට යාමට ඔබගේ මුහුණ භාවිත කරන්න"
"ඉදිරියට යාමට ඔබගේ මුහුණු හෝ තිර අගුල භාවිත කරන්න"
-
-
"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."
"මුහුණ නිරූපකය"
"සමමුහුර්ත සැකසීම් කියවන්න"
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 5a9e0c1f032d..f0a507594c47 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -665,8 +665,6 @@
"Model tváre sa nedá vytvoriť. Skúste to znova."
"Boli rozpoznané tmavé okuliare. Musí vám byť vidieť celú tvár."
"Bolo rozpoznané rúško. Musí vám byť vidieť celú tvár."
-
-
"Tvár sa nedá overiť. Hardvér nie je k dispozícii."
"Skúste znova použiť odomknutie tvárou"
"Nové údaje o tvári sa nedajú uložiť. Najprv odstráňte jeden zo starých záznamov."
@@ -684,8 +682,6 @@
"Použiť tvár alebo zámku obrazovky"
"Pokračujte pomocou tváre"
"Pokračujte použitím tváre alebo zámky obrazovky"
-
-
"Vyskytla sa chyba. Skúste to znova."
"Ikona tváre"
"čítať nastavenia synchronizácie"
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 56e1b5c4b580..d118c4575388 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -665,8 +665,6 @@
"Modela obraza ni mogoče ustvariti. Poskusite znova."
"Zaznana so temna očala. Videti se mora cel obraz."
"Zaznano je, da je obraz prekrit. Videti se mora cel obraz."
-
-
"Obraza ni mogoče preveriti. Str. opr. ni na voljo."
"Znova izvedite odklepanje z obrazom."
"Novega obraza ni mogoče shraniti. Najprej izbrišite starega."
@@ -684,8 +682,6 @@
"Uporaba odklepanja z obrazom ali s poverilnico"
"Uporabite obraz, če želite nadaljevati."
"Za nadaljevanje uporabite obraz ali odklepanje s poverilnico."
-
-
"Prišlo je do napake. Poskusite znova."
"Ikona obraza"
"branje nastavitev sinhronizacije"
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index bb55457aec64..1132c0c67683 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -663,8 +663,6 @@
"Modeli i fytyrës nuk krijohet. Provo sërish."
"U zbuluan syze të errëta. Fytyra jote duhet të jetë plotësisht e dukshme."
"U zbulua mbulim i fytyrës. Fytyra jote duhet të jetë plotësisht e dukshme."
-
-
"Fytyra s\'mund të verifikohet. Hardueri nuk ofrohet."
"Provo përsëri \"Shkyçjen me fytyrë\""
"S\'mund të ruhen të dhëna të reja fytyre. Fshi një të vjetër në fillim."
@@ -682,8 +680,6 @@
"Përdor kyçjen me fytyrë ose kyçjen e ekranit"
"Përdor fytyrën tënde për të vazhduar"
"Përdor fytyrën tënde ose kyçjen e ekranit për të vazhduar"
-
-
"Ndodhi një gabim. Provo sërish."
"Ikona e fytyrës"
"lexo cilësimet e sinkronizimit"
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 474729713186..9ae224d5ca89 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -664,8 +664,6 @@
"Прављење модела лица није успело. Пробајте поново."
"Откривене су тамне наочари. Лице мора да буде потпуно видљиво."
"Откривено је прекривање лица. Лице мора да буде потпуно видљиво."
-
-
"Провера лица није успела. Хардвер није доступан."
"Пробајте поново откључавање лицем"
"Нови подаци о лицу нису сачувани. Прво избришете претходне."
@@ -683,8 +681,6 @@
"Користите закључавање лицем или закључавање екрана"
"Потврдите идентитет лицем да бисте наставили"
"Користите лице или закључавање екрана да бисте наставили"
-
-
"Дошло је до проблема. Пробајте поново."
"Икона лица"
"читање подешавања синхронизације"
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 92e0cd6e9d1c..db4cc268fa19 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -663,8 +663,6 @@
"Ansiktsmodellen kunde inte skapas. Försök igen."
"Mörka glasögon identifierades. Hela ansiktet måste synas."
"Något som täcker ansiktet identifierades. Hela ansiktet måste synas."
-
-
"Ansiktsverifiering går ej. Otillgänglig maskinvara."
"Försök att använda ansiktslåset igen"
"Kan inte lagra ny ansiktsdata. Radera först gammal data."
@@ -682,8 +680,6 @@
"Använd ansiktslåset eller skärmlåset"
"Fortsätt med hjälp av ditt ansikte"
"Fortsätt med hjälp av ditt ansikte eller skärmlåset"
-
-
"Något gick fel. Försök igen."
"Ansikte"
"läsa synkroniseringsinställningar"
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index fae3b07a8b7b..f4099b04719d 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -663,8 +663,6 @@
"Imeshindwa kuunda muundo wa uso wako. Jaribu tena."
"Vioo vyeusi vimetambuliwa. Ni lazima uso wako wote uonekane."
"Kifuniko cha uso kimetambuliwa. Ni lazima uso wako wote uonekane."
-
-
"Imeshindwa kuthibitisha uso. Maunzi hayapatikani."
"Jaribu Kufungua kwa Uso tena"
"Imeshindwa kuhifadhi data ya uso mpya. Futa wa kale kwanza."
@@ -682,8 +680,6 @@
"Tumia uso au mbinu ya kufunga skrini"
"Tumia uso wako ili uendelee"
"Tumia uso au mbinu yako ya kufunga skrini ili uendelee"
-
-
"Hitilafu fulani imetokea. Jaribu tena."
"Aikoni ya uso"
"kusoma mipangilio ya usawazishaji"
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index b08b86b0cb39..7f7008b57a23 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -663,8 +663,6 @@
"முகத் தோற்றம் பதிவாகவில்லை. மீண்டும் முயலவும்."
"அடர் நிறக் கண்ணாடிகள் கண்டறியப்பட்டுள்ளது. உங்கள் முகத்தை முழுமையாகக் காட்டவும்."
"முகம் மறைக்கப்பட்டுள்ளது. உங்கள் முகத்தை முழுமையாகக் காட்டவும்."
-
-
"முகத்தைச் சரிபார்க்க இயலவில்லை. வன்பொருள் இல்லை."
"மீண்டும் \'முகம் காட்டித் திறத்தலை\' உபயோகிக்கவும்"
"புதிய முகங்களைச் சேர்க்க இயலவில்லை. பழையது ஒன்றை நீக்கவும்."
@@ -682,8 +680,6 @@
"முகம் காட்டித் திறத்தல் / திரைப் பூட்டைப் பயன்படுத்து"
"தொடர்வதற்கு உங்கள் முகத்தைப் பயன்படுத்துங்கள்"
"தொடர, உங்கள் முகத்தையோ திரைப் பூட்டையோ பயன்படுத்துங்கள்"
-
-
"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."
"முக ஐகான்"
"ஒத்திசைவு அமைப்புகளைப் படித்தல்"
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index c946894bcd54..3c706ff321c7 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -663,8 +663,6 @@
"మీ ఫేస్మోడల్ క్రియేషన్ కుదరదు. మళ్లీ ట్రై చేయండి."
"డార్క్ గ్లాసెస్ గుర్తించబడ్డాయి. మీ ముఖం పూర్తిగా కనిపించాలి."
"ముఖం కవర్ చేయబడింది. మీ ముఖం పూర్తిగా కనిపించాలి."
-
-
"ముఖం ధృవీకరించలేరు. హార్డ్వేర్ అందుబాటులో లేదు."
"ఫేస్ అన్లాక్ను మళ్లీ ట్రై చేయండి"
"కొత్త ముఖం డేటాను నిల్వ చేయడం కాదు. మొదట పాతది తొలిగించండి."
@@ -682,8 +680,6 @@
"ఫేస్ లేదా స్క్రీన్ లాక్ను ఉపయోగించండి"
"కొనసాగించడానికి మీ ముఖాన్ని ఉపయోగించండి"
"కొనసాగించడానికి మీ ముఖం లేదా స్క్రీన్ లాక్ను ఉపయోగించండి"
-
-
"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."
"ముఖ చిహ్నం"
"సింక్ సెట్టింగ్లను చదవగలగడం"
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 6af51659b336..95eabdabff31 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -663,8 +663,6 @@
"สร้างรูปแบบใบหน้าไม่ได้ โปรดลองอีกครั้ง"
"ตรวจพบแว่นตาดำ ต้องมองเห็นใบหน้าของคุณทั้งหมด"
"ตรวจพบหน้ากากอนามัย ต้องมองเห็นใบหน้าของคุณทั้งหมด"
-
-
"ยืนยันใบหน้าไม่ได้ ฮาร์ดแวร์ไม่พร้อมใช้งาน"
"ลองใช้การปลดล็อกด้วยใบหน้าอีกครั้ง"
"จัดเก็บข้อมูลใบหน้าใหม่ไม่ได้ ลบข้อมูลเก่าออกไปก่อน"
@@ -682,8 +680,6 @@
"ใช้การล็อกด้วยใบหน้าหรือการล็อกหน้าจอ"
"ใช้ใบหน้าของคุณเพื่อดำเนินการต่อ"
"ใช้ใบหน้าหรือการล็อกหน้าจอเพื่อดำเนินการต่อ"
-
-
"เกิดข้อผิดพลาด ลองอีกครั้ง"
"ไอคอนใบหน้า"
"อ่านการตั้งค่าการซิงค์"
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 7bb0ba9c91da..1e8880bf779f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -663,8 +663,6 @@
"Hindi magawa ang iyong face model. Subukan ulit."
"May na-detect na madilim na salamin. Dapat ganap na nakikita ang iyong mukha."
"May na-detect na pantakip sa mukha. Dapat ganap na nakikita ang iyong mukha."
-
-
"Di ma-verify ang mukha. Di available ang hardware."
"Subukan ulit ang Pag-unlock Gamit ang Mukha"
"Hindi ma-store ang data ng mukha. Mag-delete muna ng iba."
@@ -682,8 +680,6 @@
"Gumamit ng mukha o lock ng screen"
"Gamitin ang iyong mukha para magpatuloy"
"Gamitin ang iyong mukha o lock ng screen para magpatuloy"
-
-
"Nagkaproblema. Subukan ulit."
"Face icon"
"basahin ang mga setting ng sync"
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c9c2d113121f..65755f7256e3 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -663,8 +663,6 @@
"Yüzünüzün modeli oluşturulamıyor. Tekrar deneyin."
"Koyu renk gözlükler algılandı. Yüzünüz tamamen görünür olmalıdır."
"Yüzünüzü kapattığınız algılandı. Yüzünüz tamamen görünür olmalıdır."
-
-
"Yüz doğrulanamıyor. Donanım kullanılamıyor."
"Yüz Tanıma Kilidi\'ni yeniden deneyin"
"Yeni yüz verisi depolanamıyor. Önce eski bir tanesini silin."
@@ -682,8 +680,6 @@
"Yüz tanıma veya ekran kilidi kullan"
"Devam etmek için yüzünüzü kullanın"
"Devam etmek için yüz veya ekran kilidinizi kullanın"
-
-
"Bir hata oluştu. Tekrar deneyin."
"Yüz simgesi"
"senk. ayarlarını okuma"
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 163c629dbaa9..7056972d8478 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -665,8 +665,6 @@
"Не вдається створити модель обличчя. Повторіть спробу."
"Виявлено темні окуляри. Обличчя має бути видно повністю."
"Виявлено аксесуар, який закриває обличчя. Обличчя має бути видно повністю."
-
-
"Не вдається перевірити обличчя. Апаратне забезпечення недоступне."
"Скористайтеся фейсконтролем ще раз"
"Не вдається зберегти нові дані про обличчя. Видаліть старі."
@@ -684,8 +682,6 @@
"Використовувати фейсконтроль або дані для розблокування екрана"
"Щоб продовжити, скористайтеся фейсконтролем"
"Щоб продовжити, скористайтеся фейсконтролем або даними для розблокування екрана"
-
-
"Сталася помилка. Повторіть спробу."
"Значок обличчя"
"читати налаштування синхронізації"
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 94f5ab525cd4..17aa7072ca6a 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -663,8 +663,6 @@
"آپکے چہرے کا ماڈل تخلیق نہیں ہو سکا۔ پھر کوشش کریں۔"
"گہرے چشمے کا پتہ چلا۔ آپ کا چہرہ مکمل طور پر دکھائی دینا ضروری ہے۔"
"چہرے کو ڈھانپنے کا پتہ چلا۔ آپ کا چہرہ مکمل طور پر دکھائی دینا ضروری ہے۔"
-
-
"چہرے کی توثیق نہیں کی جا سکی۔ ہارڈ ویئر دستیاب نہیں ہے۔"
"فیس اَنلاک کو دوبارہ آزمائیں"
"چہرے کا نیا ڈیٹا اسٹور نہیں کر سکتے۔ پہلے پرانا حذف کریں۔"
@@ -682,8 +680,6 @@
"فیس یا اسکرین لاک استعمال کریں"
"جاری رکھنے کے لیے اپنے چہرے کا استعمال کریں"
"جاری رکھنے کے لیے اپنے چہرے یا اسکرین لاک کا استعمال کریں"
-
-
"کچھ غلط ہو گیا۔ دوبارہ کوشش کریں۔"
"چہرے کا آئیکن"
"مطابقت پذیری کی ترتیبات پڑھیں"
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 92b231526354..4ec719bc7838 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -663,8 +663,6 @@
"Yuzingiz modeli yaratilmadi. Qayta urining."
"Qora koʻzoynak aniqlandi. Yuzingiz toʻliq koʻrinishi kerak."
"Yuzning bir qismi yopilib qolgan. Yuzingiz toʻliq koʻrinishi kerak."
-
-
"Yuzingiz tasdiqlanmadi. Qurilma ishlamayapti."
"Yana yuz bilan ochishga urining"
"Yuzga oid axborot saqlanmadi. Avval eskilari tozalansin."
@@ -682,8 +680,6 @@
"Yuz bilan ochish yoki ekran qulfi"
"Yuz tekshiruvi bilan davom eting"
"Davom etish uchun yuz tekshiruvi yoki ekran qulfidan foydalaning"
-
-
"Xatolik yuz berdi. Qayta urining."
"Yuz belgisi"
"sinx-sh sozlamalarini o‘qish"
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index f78c64e6a957..fb009ef4e607 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -663,8 +663,6 @@
"Không thể tạo mẫu khuôn mặt của bạn. Hãy thử lại."
"Đã phát hiện thấy kính râm. Toàn bộ khuôn mặt của bạn phải được trông thấy rõ ràng."
"Đã phát hiện khuôn mặt bị che khuất. Toàn bộ khuôn mặt của bạn phải được hiển thị."
-
-
"Không thể xác minh khuôn mặt. Phần cứng không có sẵn."
"Hãy thử lại thao tác Mở khóa bằng khuôn mặt"
"Không lưu được dữ liệu khuôn mặt mới. Hãy xóa dữ liệu cũ trước."
@@ -682,8 +680,6 @@
"Dùng khuôn mặt hoặc phương thức khóa màn hình"
"Hãy dùng khuôn mặt của bạn để tiếp tục"
"Dùng khuôn mặt của bạn hoặc phương thức khóa màn hình để tiếp tục"
-
-
"Đã xảy ra lỗi. Hãy thử lại."
"Biểu tượng khuôn mặt"
"đọc cài đặt đồng bộ hóa"
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 023d9d1f67d2..d5202f57fc71 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -663,8 +663,6 @@
"无法创建您的脸部模型,请重试。"
"检测到墨镜,您的脸部必须完全可见。"
"检测到脸部有遮挡物,您的脸部必须完全可见。"
-
-
"无法验证人脸。硬件无法使用。"
"请重新尝试人脸解锁"
"无法存储新的人脸数据。请先删除旧的人脸数据。"
@@ -682,8 +680,6 @@
"使用人脸解锁或屏幕锁定凭据"
"使用您的面孔验证身份才能继续"
"使用人脸解锁或屏幕锁定凭据验证身份,才能继续操作"
-
-
"出了点问题。请重试。"
"面孔图标"
"读取同步设置"
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c67f9fa598ea..27de26cbabec 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -663,8 +663,6 @@
"無法建立面部模型,請再試一次。"
"偵測到深色眼鏡。您必須展示整個面孔。"
"偵測到面部遮蓋物。您必須展示整個面孔。"
-
-
"無法驗證面孔,硬件無法使用。"
"請再次嘗試「面孔解鎖」"
"無法儲存新的臉容資料,請先刪除舊資料。"
@@ -682,8 +680,6 @@
"使用面孔或螢幕鎖定"
"如要繼續操作,請使用您的面孔驗證身分"
"請使用面孔解鎖或螢幕鎖定功能驗證身分,才能繼續操作"
-
-
"發生錯誤,請再試一次。"
"面孔圖示"
"讀取同步處理設定"
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 3da603d33e1e..723bf3abc994 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -663,8 +663,6 @@
"無法建立臉部模型,請再試一次。"
"偵測到墨鏡,請露出整張臉。"
"偵測到有物品遮住臉,請露出整張臉。"
-
-
"相關硬體無法使用,因此無法驗證臉孔。"
"請重新進行人臉解鎖"
"無法儲存新的臉孔資料,請先刪除舊的資料。"
@@ -682,8 +680,6 @@
"使用人臉解鎖或螢幕鎖定功能"
"如要繼續操作,請透過你的臉孔驗證身分"
"請使用人臉解鎖或螢幕鎖定功能驗證身分,才能繼續操作"
-
-
"發生錯誤,請再試一次。"
"臉孔圖示"
"讀取同步處理設定"
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 9028854b506a..9eb395ede883 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -663,8 +663,6 @@
"Ayikwazi ukusungula imodeli yobuso bakho. Zama futhi."
"Kutholwe izibuko ezimnyama. Ubuso bakho kufanele bubonakale ngokugcwele."
"Kutholwe ukumbozwa kobuso. Ubuso bakho kufanele bubonakale ngokugcwele."
-
-
"Ayikwazi ukuqinisekisa ubuso. Izingxenyekazi zekhompyutha azitholakali."
"Zama Ukuvula ngobuso futhi."
"Ayikwazi ukulondoloza idatha yobuso. Susa endala."
@@ -682,8 +680,6 @@
"Sebenzisa i-face lock noma ukukhiya isikrini"
"Sebenzisa ubuso bakho ukuze uqhubeke"
"Sebenzisa ubuso bakho noma ukukhiya isikrini ukuze uqhubeke"
-
-
"Kunento engahambanga kahle. Zama futhi."
"Isithonjana sobuso"
"funda izilungiselelo zokuvumelanisa"
diff --git a/core/res/res/values/bootleg_arrays.xml b/core/res/res/values/bootleg_arrays.xml
new file mode 100644
index 000000000000..ee003774d75c
--- /dev/null
+++ b/core/res/res/values/bootleg_arrays.xml
@@ -0,0 +1,9 @@
+
+
+
+ - restart
+ - reboot_recovery
+ - reboot_bootloader
+
+
+
diff --git a/core/res/res/values/bootleg_colors.xml b/core/res/res/values/bootleg_colors.xml
new file mode 100644
index 000000000000..aede057fa5e9
--- /dev/null
+++ b/core/res/res/values/bootleg_colors.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+ @*android:color/system_accent3_600
+
+
+ @*android:color/system_accent1_100
+ @*android:color/system_accent1_900
+
+
+ #025fee
+ #ee9002
+ #02d6ee
+ #9002ee
+ #ee0260
+ #00b200
+ #7200b6
+ #006f72
+ #eed315
+
diff --git a/core/res/res/values/bootleg_config.xml b/core/res/res/values/bootleg_config.xml
new file mode 100644
index 000000000000..e0d935402820
--- /dev/null
+++ b/core/res/res/values/bootleg_config.xml
@@ -0,0 +1,147 @@
+
+
+
+
+
+ true
+
+
+ false
+
+
+ sans-serif-light
+
+
+ sans-serif-regular
+
+
+
+
+
+
+ false
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+ - @string/face_unlock_disabled_idle
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ 9
+
+
+
+
+
+
+
+
+
+
+
+ - com.android.contacts
+ - com.android.chrome
+ - com.android.documentsui
+ - com.android.gallery3d
+ - com.android.vending
+ - com.google.android.apps.docs
+ - com.google.android.apps.messaging
+ - com.google.android.apps.nbu.files
+ - com.google.android.apps.photos
+ - com.google.android.apps.recorder
+ - com.google.android.contacts
+ - com.google.android.dialer
+ - com.google.android.gm
+ - com.google.android.googlequicksearchbox
+ - com.google.android.keep
+ - com.google.android.youtube
+ - org.lineageos.recorder
+ - org.lineageos.aperture
+
+
+
+ true
+
+
+ false
+ 250
+ false
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+ false
+
diff --git a/core/res/res/values/bootleg_dimens.xml b/core/res/res/values/bootleg_dimens.xml
new file mode 100644
index 000000000000..3b19bd7a9ce5
--- /dev/null
+++ b/core/res/res/values/bootleg_dimens.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ 350dp
+ 175dp
+ 56dp
+ 24sp
+ 56dp
+ 16sp
+ 56dp
+ 24dp
+ 14sp
+ 8dp
+
diff --git a/core/res/res/values/bootleg_strings.xml b/core/res/res/values/bootleg_strings.xml
new file mode 100644
index 000000000000..a1647946e45a
--- /dev/null
+++ b/core/res/res/values/bootleg_strings.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+ Face unlock disabled due to inactivity
+
+
+ Reboot bootloader
+ Rebooting to bootloader\u2026
+ Reboot recovery
+ Rebooting to recovery\u2026
+ Restart system
+ Restarting system\u2026
+
+
+ %1$s
+
+
+ Unlock %1$s
+
+
+ Press and hold power button to unlock
+ Pocket mode is on
+ To use your phone:
+ Check if the blue area of your phone is clear of any obstructions, and clean off any dirt or dust.
+ Long press the power button to force quit pocket mode.
+ 1.\u0020
+ 2.\u0020
+
+
+
diff --git a/core/res/res/values/bootleg_styles.xml b/core/res/res/values/bootleg_styles.xml
new file mode 100644
index 000000000000..4209e6cc8cde
--- /dev/null
+++ b/core/res/res/values/bootleg_styles.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/values/bootleg_symbols.xml b/core/res/res/values/bootleg_symbols.xml
new file mode 100644
index 000000000000..57551a973bd8
--- /dev/null
+++ b/core/res/res/values/bootleg_symbols.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 4c5a008a3402..5d3d6a3155a9 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -59,7 +59,7 @@
@color/system_neutral1_700
@color/system_neutral2_100
@color/system_neutral1_800
- @color/system_neutral1_0
+ @color/system_neutral1_10
@color/text_color_primary_device_default_light
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5d1acbc5a07a..6b16a528fbb9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -58,10 +58,13 @@
- @string/status_bar_ethernet
- @string/status_bar_wifi
- @string/status_bar_hotspot
+ - @string/status_bar_ims
- @string/status_bar_mobile
- @string/status_bar_airplane
- @string/status_bar_battery
- @string/status_bar_sensors_off
+ - @string/status_bar_center_clock
+ - @string/status_bar_right_clock
rotate
@@ -100,6 +103,9 @@
call_strength
sensors_off
screen_record
+ center_clock
+ right_clock
+ ims
- 200
+ 100
- 400
+ 200
- 500
+ 250
- 150
- 220
+ 75
+ 110
116
@@ -3216,6 +3222,7 @@
- lockdown
- power
- restart
+ - recovery
- logout
- screenshot
- bugreport
@@ -3797,7 +3804,7 @@
-
+ com.android.statementservice,com.android.systemui
@@ -4350,7 +4357,7 @@
90
-
+ @string/config_bodyFontFamily
@@ -4428,7 +4435,7 @@
true
- @string/font_family_button_material
+ @string/config_bodyFontFamilyMedium
sans-serif
diff --git a/core/res/res/values/donottranslate_material.xml b/core/res/res/values/donottranslate_material.xml
index 9cf9f6cfa86d..013b9a8ecb9e 100644
--- a/core/res/res/values/donottranslate_material.xml
+++ b/core/res/res/values/donottranslate_material.xml
@@ -17,16 +17,16 @@
sans-serif-light
- sans-serif
- sans-serif
- sans-serif
- sans-serif
- sans-serif-medium
- sans-serif
- sans-serif
- sans-serif-medium
- sans-serif
- sans-serif
- sans-serif-medium
+ @string/config_bodyFontFamily
+ @string/config_bodyFontFamily
+ @string/config_bodyFontFamily
+ @string/config_headlineFontFamily
+ @string/config_headlineFontFamilyMedium
+ @string/config_bodyFontFamily
+ @string/config_bodyFontFamily
+ @string/config_bodyFontFamilyMedium
+ @string/config_bodyFontFamily
+ @string/config_bodyFontFamily
+ @string/config_bodyFontFamilyMedium
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5763345aba4d..9e82d0dbb1b5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -974,6 +974,18 @@
+
+ Spoof package signature
+
+ Allows the app to pretend to be a different app. Malicious applications might be able to use this to access private application data. Legitimate uses include an emulator pretending to be what it emulates. Grant this permission with caution only!
+
+ Spoof package signature
+
+ allow to spoof package signature
+
+ Allow
+ <b>%1$s</b> to spoof package signature?
+
disable or modify status bar
@@ -1894,9 +1906,6 @@
Use your face or screen lock to continue
-
-
-
Something went wrong. Try again.
@@ -5190,16 +5199,16 @@
--
- sans-serif
+ @string/config_bodyFontFamily
- sans-serif
+ @string/config_bodyFontFamily
- sans-serif-medium
+ @string/config_bodyFontFamilyMedium
- sans-serif-medium
+ @string/config_bodyFontFamilyMedium
- sans-serif-medium
+ @string/config_bodyFontFamilyMedium
Ask for PIN before unpinning
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index bad05e077b7d..884581cf4a8e 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -974,7 +974,7 @@ please see styles_device_defaults.xml.
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index eec6ae3fb521..2446054d8967 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -429,7 +429,7 @@ please see styles_device_defaults.xml.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6e574bd788a9..eb1f6e6ac7c8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3134,6 +3134,7 @@
+
@@ -4854,4 +4855,7 @@
+
+
+
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index c603c83e033d..721812b76d9a 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1089,6 +1089,7 @@ easier.
- @style/TextAppearance.DeviceDefault.Widget.Button
+ - @style/TextAppearance.DeviceDefault.Medium
- @dimen/config_buttonCornerRadius
@@ -2154,6 +2155,7 @@ easier.
- @style/TextAppearance.DeviceDefault.Widget.Button
+ - @style/TextAppearance.DeviceDefault.Medium
- @dimen/config_buttonCornerRadius
@@ -2299,8 +2301,8 @@ easier.
- @color/edge_effect_device_default_light
- - @color/navigation_bar_divider_device_default_settings
- - @android:color/white
+ - @null
+ - ?attr/colorBackground
- true
diff --git a/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java
index 1cf430205627..372bca4664a2 100644
--- a/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java
@@ -88,6 +88,7 @@ public void timeReadWritePointArrayFast(int reps) {
}
}
+ @SuppressWarnings("ParcelableCreator")
@SuppressLint("ParcelCreator")
private static class PointArray implements Parcelable {
Rect mBounds = new Rect();
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerPropertyTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerPropertyTests.java
index d505492f3b80..86e958320a04 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerPropertyTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerPropertyTests.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
import android.content.pm.PackageManager.Property;
@@ -162,40 +163,30 @@ public void testStringPropertyToBundle() throws Exception {
@Test
public void testProperty_invalidName() throws Exception {
- try {
+ assertThrows(NullPointerException.class, () -> {
final Property p = new Property(null, 1, "android", null);
- fail("expected assertion error");
- } catch (AssertionError expected) {
- }
+ });
}
@Test
public void testProperty_invalidType() throws Exception {
- try {
+ assertThrows(IllegalArgumentException.class, () -> {
final Property p = new Property("invalidTypeProperty", 0, "android", null);
- fail("expected assertion error");
- } catch (AssertionError expected) {
- }
+ });
- try {
+ assertThrows(IllegalArgumentException.class, () -> {
final Property p = new Property("invalidTypeProperty", 6, "android", null);
- fail("expected assertion error");
- } catch (AssertionError expected) {
- }
+ });
- try {
+ assertThrows(IllegalArgumentException.class, () -> {
final Property p = new Property("invalidTypeProperty", -1, "android", null);
- fail("expected assertion error");
- } catch (AssertionError expected) {
- }
+ });
}
@Test
public void testProperty_noPackageName() throws Exception {
- try {
+ assertThrows(NullPointerException.class, () -> {
final Property p = new Property(null, 1, null, null);
- fail("expected assertion error");
- } catch (AssertionError expected) {
- }
+ });
}
}
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
index 00b3693c902b..bbf9f3c99402 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
@@ -128,6 +128,7 @@ public void clone_child_fails() {
RemoteViews clone = child.clone();
}
+ @SuppressWarnings("ReturnValueIgnored")
@Test
public void clone_repeatedly() {
RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
@@ -485,6 +486,7 @@ public View waitAndGetView() throws Exception {
}
}
+ @SuppressWarnings("ReturnValueIgnored")
@Test
public void nestedAddViews() {
RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
@@ -509,6 +511,7 @@ public void nestedAddViews() {
parcelAndRecreate(views);
}
+ @SuppressWarnings("ReturnValueIgnored")
@Test
public void nestedLandscapeViews() {
RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 82b2bf4185e6..8207c9ee5ff3 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -1054,10 +1054,23 @@ class TestBinderCallsStats extends BinderCallsStats {
super(new Injector() {
public Random getRandomGenerator() {
return new Random() {
- int mCallCount = 0;
+ int mCallCount = -1;
public int nextInt() {
- return mCallCount++;
+ throw new IllegalStateException("Should not use nextInt()");
+ }
+
+ public int nextInt(int x) {
+ if (mCallCount == -1) {
+ // The tests are written such that they expect
+ // the first call to nextInt() to be on the first
+ // callEnded(). However, the BinderCallsStats
+ // constructor also calls nextInt(). Fake 0 being
+ // rolled twice.
+ mCallCount++;
+ return 0;
+ }
+ return (mCallCount++) % x;
}
};
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
index 5af7376dc132..7bd53b9d4fcc 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
@@ -98,7 +98,7 @@ public void testSampling() {
assertEquals(1, latencyHistograms.size());
LatencyDims dims = latencyHistograms.keySet().iterator().next();
assertEquals(binder.getClass(), dims.getBinderClass());
- assertEquals(1, dims.getTransactionCode());
+ assertEquals(2, dims.getTransactionCode()); // the first nextInt() is in the constructor
assertThat(latencyHistograms.get(dims)).asList().containsExactly(1, 0, 0, 0, 0).inOrder();
}
@@ -313,11 +313,11 @@ public Random getRandomGenerator() {
int mCallCount = 0;
public int nextInt() {
- return mCallCount++;
+ throw new IllegalStateException("Should not use nextInt()");
}
public int nextInt(int x) {
- return 1;
+ return (mCallCount++) % x;
}
};
}
diff --git a/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java b/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java
index 6c50bce86638..8b30828a8936 100644
--- a/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import static org.junit.Assert.assertThrows;
+
import android.os.SystemClock;
import android.text.format.DateUtils;
@@ -170,10 +172,9 @@ void assertDuration(long expected, long elapsed) {
}
void assertThrow(Fn fn) {
- try {
+ assertThrows(Throwable.class, () -> {
fn.call();
- fail("expected n exception to be thrown.");
- } catch (Throwable t) { }
+ });
}
interface Fn { void call(); }
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/src/com/android/multidexlegacytestapp/Test.java b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/src/com/android/multidexlegacytestapp/Test.java
index 41b8956f55d0..a2263256508b 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/src/com/android/multidexlegacytestapp/Test.java
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/src/com/android/multidexlegacytestapp/Test.java
@@ -31,6 +31,7 @@ public void testAllClassesAvailable() {
assertEquals(3366, getActivity().getValue());
}
+ @SuppressWarnings("ReturnValueIgnored")
public void testAnnotation() throws Exception {
assertEquals(ReferencedByAnnotation.B,
((AnnotationWithEnum) TestApplication.annotation).value());
diff --git a/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java b/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java
index c53f4cc7ee52..1581abb5a9c6 100644
--- a/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java
@@ -20,6 +20,7 @@
import org.junit.Test;
import java.util.ArrayList;
+import java.util.Objects;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -39,11 +40,11 @@ public class CallbackRegistryTest extends TestCase {
Integer argValue;
private void addNotifyCount(Integer callback) {
- if (callback == callback1) {
+ if (Objects.equals(callback, callback1)) {
notify1++;
- } else if (callback == callback2) {
+ } else if (Objects.equals(callback, callback2)) {
notify2++;
- } else if (callback == callback3) {
+ } else if (Objects.equals(callback, callback3)) {
notify3++;
}
deepNotifyCount[callback]++;
@@ -114,7 +115,7 @@ public void testRemoveWhileNotifying() {
public void onNotifyCallback(Integer callback, CallbackRegistryTest sender,
int arg1, Integer arg) {
addNotifyCount(callback);
- if (callback == callback1) {
+ if (Objects.equals(callback, callback1)) {
registry.remove(callback1);
registry.remove(callback2);
}
@@ -166,9 +167,9 @@ public void testAddRemovedListener() {
public void onNotifyCallback(Integer callback, CallbackRegistryTest sender,
int arg1, Integer arg) {
addNotifyCount(callback);
- if (callback == callback1) {
+ if (Objects.equals(callback, callback1)) {
registry.remove(callback2);
- } else if (callback == callback3) {
+ } else if (Objects.equals(callback, callback3)) {
registry.add(callback2);
}
}
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 36a51341f52d..25245b87ecb6 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -25,5 +25,9 @@
+
+
+
+
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index 5dcc5998850b..1f1c4987bd7d 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -27,6 +27,7 @@
+
@@ -46,6 +47,7 @@
+
@@ -62,5 +64,7 @@
+
+
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index e0e13f59b706..1592f2001429 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -28,6 +28,7 @@
+
@@ -82,5 +83,7 @@
+
+
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 9a1b8a90dbfd..e632a671f4a3 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -212,6 +212,9 @@
+
+
+
@@ -334,4 +337,6 @@
+
+
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 58a2073981bf..c71084a0dfcf 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -42,6 +42,7 @@ applications that come with the platform
+
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index fe6eeeb66e40..3c7178022261 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -498,7 +498,7 @@ key PLUS {
### Non-printing keys ###
key ESCAPE {
- base: none
+ base: fallback BACK
alt, meta: fallback HOME
ctrl: fallback MENU
}
diff --git a/data/videos/AndroidInSpace.240p.mp4 b/data/videos/AndroidInSpace.240p.mp4
deleted file mode 100644
index e1445e493c76..000000000000
Binary files a/data/videos/AndroidInSpace.240p.mp4 and /dev/null differ
diff --git a/data/videos/AndroidInSpace.480p.lq.mp4 b/data/videos/AndroidInSpace.480p.lq.mp4
deleted file mode 100644
index f1db6942ebd2..000000000000
Binary files a/data/videos/AndroidInSpace.480p.lq.mp4 and /dev/null differ
diff --git a/data/videos/AndroidInSpace.480p.mq.mp4 b/data/videos/AndroidInSpace.480p.mq.mp4
deleted file mode 100644
index 5f4cfb3c33b7..000000000000
Binary files a/data/videos/AndroidInSpace.480p.mq.mp4 and /dev/null differ
diff --git a/data/videos/Disco.240p.mp4 b/data/videos/Disco.240p.mp4
deleted file mode 100644
index c9078b736f90..000000000000
Binary files a/data/videos/Disco.240p.mp4 and /dev/null differ
diff --git a/data/videos/Disco.480p.lq.mp4 b/data/videos/Disco.480p.lq.mp4
deleted file mode 100644
index 411e0d5dacd5..000000000000
Binary files a/data/videos/Disco.480p.lq.mp4 and /dev/null differ
diff --git a/data/videos/Disco.480p.mq.mp4 b/data/videos/Disco.480p.mq.mp4
deleted file mode 100644
index 3dc495764b82..000000000000
Binary files a/data/videos/Disco.480p.mq.mp4 and /dev/null differ
diff --git a/data/videos/Sunset.240p.mp4 b/data/videos/Sunset.240p.mp4
deleted file mode 100644
index f5c533f0f9f5..000000000000
Binary files a/data/videos/Sunset.240p.mp4 and /dev/null differ
diff --git a/data/videos/Sunset.480p.lq.mp4 b/data/videos/Sunset.480p.lq.mp4
deleted file mode 100644
index 7f9d6a1e6888..000000000000
Binary files a/data/videos/Sunset.480p.lq.mp4 and /dev/null differ
diff --git a/data/videos/Sunset.480p.mq.mp4 b/data/videos/Sunset.480p.mq.mp4
deleted file mode 100644
index 7691544f019e..000000000000
Binary files a/data/videos/Sunset.480p.mq.mp4 and /dev/null differ
diff --git a/data/videos/VideoPackage1.mk b/data/videos/VideoPackage1.mk
deleted file mode 100644
index ee3b5ed321dc..000000000000
--- a/data/videos/VideoPackage1.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-
-# Lower-quality videos for space-constrained devices
-
-LOCAL_PATH := frameworks/base/data/videos
-TARGET_PATH := system/media/video
-
-#PRODUCT_COPY_FILES += \
-# $(LOCAL_PATH)/AndroidInSpace.240p.mp4:$(TARGET_PATH)/AndroidInSpace.240p.mp4 \
-# $(LOCAL_PATH)/AndroidInSpace.480p.lq.mp4:$(TARGET_PATH)/AndroidInSpace.480p.mp4 \
-# $(LOCAL_PATH)/Sunset.240p.mp4:$(TARGET_PATH)/Sunset.240p.mp4 \
-# $(LOCAL_PATH)/Sunset.480p.lq.mp4:$(TARGET_PATH)/Sunset.480p.mp4
diff --git a/data/videos/VideoPackage2.mk b/data/videos/VideoPackage2.mk
deleted file mode 100644
index f799bea2c147..000000000000
--- a/data/videos/VideoPackage2.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-
-# Good-quality videos for non-space-constrained devices
-
-LOCAL_PATH := frameworks/base/data/videos
-TARGET_PATH := system/media/video
-
-#PRODUCT_COPY_FILES += \
-# $(LOCAL_PATH)/AndroidInSpace.240p.mp4:$(TARGET_PATH)/AndroidInSpace.240p.mp4 \
-# $(LOCAL_PATH)/AndroidInSpace.480p.mq.mp4:$(TARGET_PATH)/AndroidInSpace.480p.mp4 \
-# $(LOCAL_PATH)/Sunset.240p.mp4:$(TARGET_PATH)/Sunset.240p.mp4 \
-# $(LOCAL_PATH)/Sunset.480p.mq.mp4:$(TARGET_PATH)/Sunset.480p.mp4
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientXmlChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientXmlChecker.java
index 8706a68226ef..42e304699cd4 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientXmlChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientXmlChecker.java
@@ -168,6 +168,7 @@ public final class EfficientXmlChecker extends BugChecker
*/
private static final Matcher CONVERT_PRIMITIVE_TO_STRING =
new Matcher() {
+ @SuppressWarnings("TreeToString") //TODO: Fix me
@Override
public boolean matches(ExpressionTree tree, VisitorState state) {
if (PRIMITIVE_TO_STRING.matches(tree, state)) {
@@ -205,6 +206,7 @@ public boolean matches(ExpressionTree tree, VisitorState state) {
*/
private static final Matcher CONVERT_STRING_TO_PRIMITIVE =
new Matcher() {
+ @SuppressWarnings("TreeToString") //TODO: Fix me
@Override
public boolean matches(ExpressionTree tree, VisitorState state) {
if (PRIMITIVE_PARSE.matches(tree, state)) {
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 451b99ea7550..e60d506a171b 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -253,7 +253,7 @@ private static class NoImagePreloadHolder {
// These flags are always set on a new/reset paint, even if flags 0 is passed.
static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG
- | FILTER_BITMAP_FLAG;
+ | FILTER_BITMAP_FLAG | SUBPIXEL_TEXT_FLAG;
/**
* Font hinter option that disables font hinting.
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index a2f5301e353f..722f63c4e0a0 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -29,6 +29,7 @@
import android.annotation.UiThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
+import android.content.res.Resources;
import android.graphics.fonts.Font;
import android.graphics.fonts.FontFamily;
import android.graphics.fonts.FontStyle;
@@ -67,11 +68,13 @@
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -141,6 +144,8 @@ public class Typeface {
private static final LruCache sDynamicTypefaceCache = new LruCache<>(16);
private static final Object sDynamicCacheLock = new Object();
+ // For dynamic default font styles
+ private static final HashMap sSystemFontOverrides = new HashMap<>();
@GuardedBy("SYSTEM_FONT_MAP_LOCK")
static Typeface sDefaultTypeface;
@@ -884,7 +889,7 @@ public CustomFallbackBuilder(@NonNull FontFamily family) {
* @return The best matching typeface.
*/
public static Typeface create(String familyName, @Style int style) {
- return create(getSystemDefaultTypeface(familyName), style);
+ return create(getSystemOverrideTypeface(familyName), style);
}
/**
@@ -1176,6 +1181,11 @@ private Typeface(long ni) {
mWeight = nativeGetWeight(ni);
}
+ private static Typeface getSystemOverrideTypeface(@NonNull String familyName) {
+ Typeface tf = sSystemFontOverrides.get(familyName);
+ return tf == null ? getSystemDefaultTypeface(familyName) : tf;
+ }
+
private static Typeface getSystemDefaultTypeface(@NonNull String familyName) {
Typeface tf = sSystemFontMap.get(familyName);
return tf == null ? Typeface.DEFAULT : tf;
@@ -1345,6 +1355,60 @@ public static void setSystemFontMap(@Nullable SharedMemory sharedMemory)
}
}
+ private static void setPublicDefaults(String familyName) {
+ synchronized (SYSTEM_FONT_MAP_LOCK) {
+ sDefaults = new Typeface[] {
+ DEFAULT,
+ DEFAULT_BOLD,
+ create(getSystemDefaultTypeface(familyName), Typeface.ITALIC),
+ create(getSystemDefaultTypeface(familyName), Typeface.BOLD_ITALIC),
+ };
+ }
+ }
+
+ private static void setFinalField(String fieldName, Typeface value) {
+ synchronized (SYSTEM_FONT_MAP_LOCK) {
+ try {
+ Field field = Typeface.class.getDeclaredField(fieldName);
+ // isAccessible bypasses final on ART
+ field.setAccessible(true);
+ field.set(null, value);
+ field.setAccessible(false);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ Log.e(TAG, "Failed to set Typeface." + fieldName, e);
+ }
+ }
+ }
+
+ /** @hide */
+ public static void updateDefaultFont(Resources res) {
+ synchronized (SYSTEM_FONT_MAP_LOCK) {
+ String familyName = res.getString(com.android.internal.R.string.config_bodyFontFamily);
+ Typeface typeface = sSystemFontMap.get(familyName);
+ if (typeface == null) {
+ // This should never happen, but if the system font family name is invalid, just return
+ // instead of crashing the app.
+ return;
+ }
+
+ setDefault(typeface);
+
+ // Static typefaces in public API
+ setFinalField("DEFAULT", create(getSystemDefaultTypeface(familyName), 0));
+ setFinalField("DEFAULT_BOLD", create(getSystemDefaultTypeface(familyName), Typeface.BOLD));
+ setFinalField("SANS_SERIF", DEFAULT);
+
+ // For default aliases used in framework styles
+ sSystemFontOverrides.put("sans-serif", typeface);
+ sSystemFontOverrides.put("sans-serif-thin", create(typeface, 100, false));
+ sSystemFontOverrides.put("sans-serif-light", create(typeface, 300, false));
+ sSystemFontOverrides.put("sans-serif-medium", create(typeface, 500, false));
+ sSystemFontOverrides.put("sans-serif-black", create(typeface, 900, false));
+
+ setPublicDefaults(familyName);
+ }
+ }
+
/** @hide */
@VisibleForTesting
public static void setSystemFontMap(Map systemFontMap) {
@@ -1365,12 +1429,7 @@ public static void setSystemFontMap(Map systemFontMap) {
nativeForceSetStaticFinalField("SERIF", create("serif", 0));
nativeForceSetStaticFinalField("MONOSPACE", create("monospace", 0));
- sDefaults = new Typeface[]{
- DEFAULT,
- DEFAULT_BOLD,
- create((String) null, Typeface.ITALIC),
- create((String) null, Typeface.BOLD_ITALIC),
- };
+ setPublicDefaults(null);
// A list of generic families to be registered in native.
// https://www.w3.org/TR/css-fonts-4/#generic-font-families
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 417a27d0f506..14dc6a2513a0 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -762,7 +762,7 @@ private void onHotspotBoundsChanged() {
if (mBackground != null) {
mBackground.onHotspotBoundsChanged();
}
- float newRadius = Math.round(getComputedRadius());
+ float newRadius = getComputedRadius();
for (int i = 0; i < mRunningAnimations.size(); i++) {
RippleAnimationSession s = mRunningAnimations.get(i);
s.setRadius(newRadius);
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 4065bd110c7e..e25ee906b410 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -60,7 +60,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Map;
import java.util.Stack;
/**
@@ -1171,18 +1171,14 @@ static class VGroup extends VObject {
private static final int NATIVE_ALLOCATION_SIZE = 100;
- private static final HashMap sPropertyIndexMap =
- new HashMap() {
- {
- put("translateX", TRANSLATE_X_INDEX);
- put("translateY", TRANSLATE_Y_INDEX);
- put("scaleX", SCALE_X_INDEX);
- put("scaleY", SCALE_Y_INDEX);
- put("pivotX", PIVOT_X_INDEX);
- put("pivotY", PIVOT_Y_INDEX);
- put("rotation", ROTATION_INDEX);
- }
- };
+ private static final Map sPropertyIndexMap = Map.of(
+ "translateX", TRANSLATE_X_INDEX,
+ "translateY", TRANSLATE_Y_INDEX,
+ "scaleX", SCALE_X_INDEX,
+ "scaleY", SCALE_Y_INDEX,
+ "pivotX", PIVOT_X_INDEX,
+ "pivotY", PIVOT_Y_INDEX,
+ "rotation", ROTATION_INDEX);
static int getPropertyIndex(String propertyName) {
if (sPropertyIndexMap.containsKey(propertyName)) {
@@ -1285,18 +1281,15 @@ public Float get(VGroup object) {
}
};
- private static final HashMap sPropertyMap =
- new HashMap() {
- {
- put("translateX", TRANSLATE_X);
- put("translateY", TRANSLATE_Y);
- put("scaleX", SCALE_X);
- put("scaleY", SCALE_Y);
- put("pivotX", PIVOT_X);
- put("pivotY", PIVOT_Y);
- put("rotation", ROTATION);
- }
- };
+ private static final Map sPropertyMap = Map.of(
+ "translateX", TRANSLATE_X,
+ "translateY", TRANSLATE_Y,
+ "scaleX", SCALE_X,
+ "scaleY", SCALE_Y,
+ "pivotX", PIVOT_X,
+ "pivotY", PIVOT_Y,
+ "rotation", ROTATION);
+
// Temp array to store transform values obtained from native.
private float[] mTransform;
/////////////////////////////////////////////////////
@@ -1762,19 +1755,15 @@ static class VFullPath extends VPath {
private static final int NATIVE_ALLOCATION_SIZE = 264;
// Property map for animatable attributes.
- private final static HashMap sPropertyIndexMap
- = new HashMap () {
- {
- put("strokeWidth", STROKE_WIDTH_INDEX);
- put("strokeColor", STROKE_COLOR_INDEX);
- put("strokeAlpha", STROKE_ALPHA_INDEX);
- put("fillColor", FILL_COLOR_INDEX);
- put("fillAlpha", FILL_ALPHA_INDEX);
- put("trimPathStart", TRIM_PATH_START_INDEX);
- put("trimPathEnd", TRIM_PATH_END_INDEX);
- put("trimPathOffset", TRIM_PATH_OFFSET_INDEX);
- }
- };
+ private static final Map sPropertyIndexMap = Map.of(
+ "strokeWidth", STROKE_WIDTH_INDEX,
+ "strokeColor", STROKE_COLOR_INDEX,
+ "strokeAlpha", STROKE_ALPHA_INDEX,
+ "fillColor", FILL_COLOR_INDEX,
+ "fillAlpha", FILL_ALPHA_INDEX,
+ "trimPathStart", TRIM_PATH_START_INDEX,
+ "trimPathEnd", TRIM_PATH_END_INDEX,
+ "trimPathOffset", TRIM_PATH_OFFSET_INDEX);
// Below are the Properties that wrap the setters to avoid reflection overhead in animations
private static final Property STROKE_WIDTH =
@@ -1881,19 +1870,15 @@ public Float get(VFullPath object) {
}
};
- private final static HashMap sPropertyMap
- = new HashMap () {
- {
- put("strokeWidth", STROKE_WIDTH);
- put("strokeColor", STROKE_COLOR);
- put("strokeAlpha", STROKE_ALPHA);
- put("fillColor", FILL_COLOR);
- put("fillAlpha", FILL_ALPHA);
- put("trimPathStart", TRIM_PATH_START);
- put("trimPathEnd", TRIM_PATH_END);
- put("trimPathOffset", TRIM_PATH_OFFSET);
- }
- };
+ private static final Map sPropertyMap = Map.of(
+ "strokeWidth", STROKE_WIDTH,
+ "strokeColor", STROKE_COLOR,
+ "strokeAlpha", STROKE_ALPHA,
+ "fillColor", FILL_COLOR,
+ "fillAlpha", FILL_ALPHA,
+ "trimPathStart", TRIM_PATH_START,
+ "trimPathEnd", TRIM_PATH_END,
+ "trimPathOffset", TRIM_PATH_OFFSET);
// Temp array to store property data obtained from native getter.
private byte[] mPropertyData;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 33411e1ec5b9..88717cfff0e9 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -77,6 +77,8 @@
import javax.crypto.SecretKey;
+import com.android.internal.util.custom.PixelPropsUtils;
+
/**
* A java.security.KeyStore interface for the Android KeyStore. An instance of
* it can be created via the {@link java.security.KeyStore#getInstance(String)
@@ -164,6 +166,8 @@ private KeyEntryResponse getKeyMetadata(String alias) {
@Override
public Certificate[] engineGetCertificateChain(String alias) {
+ PixelPropsUtils.onEngineGetCertificateChain();
+
KeyEntryResponse response = getKeyMetadata(alias);
if (response == null || response.metadata.certificate == null) {
diff --git a/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml b/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml
index d29ed8b5a9ec..8835289c163e 100644
--- a/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml
+++ b/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml
@@ -42,7 +42,7 @@
android:layout_marginBottom="0dp"
android:gravity="center_horizontal"
android:textAlignment="center"
- android:fontFamily="google-sans-medium"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
android:text="@string/one_handed_tutorial_title"
android:textSize="16sp"
android:textColor="@android:color/white"/>
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml
index db96d8de4094..a02251058430 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml
@@ -37,4 +37,4 @@
android:layout_gravity="center"
android:duplicateParentState="true"
android:tint="@color/tv_pip_menu_icon" />
-
\ No newline at end of file
+
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index f170e774739f..99388c9f204c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -653,8 +653,13 @@ public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
mPipMenuController.attach(mLeash);
- final Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
+ Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
info.pictureInPictureParams, currentBounds);
+ if (sourceHintRect != null && currentBounds != null
+ && sourceHintRect.width() < currentBounds.width() / 2
+ && sourceHintRect.height() < currentBounds.height() / 3) {
+ sourceHintRect = null;
+ }
scheduleAnimateResizePip(currentBounds, destinationBounds, 0 /* startingAngle */,
sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration,
null /* updateBoundsCallback */);
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 5e8a623d4205..5825fe88a5c9 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -4387,7 +4387,7 @@ bool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* ou
if (p < 0) {
if (Res_GETPACKAGE(resID)+1 == 0) {
- ALOGW("No package identifier when getting name for resource number 0x%08x", resID);
+ ALOGV("No package identifier when getting name for resource number 0x%08x", resID);
} else {
#ifndef STATIC_ANDROIDFW_FOR_TOOLS
ALOGW("No known package when getting name for resource number 0x%08x", resID);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ad9aa6cdd3d9..33f79352b8b8 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -674,6 +674,7 @@ cc_test {
srcs: [
"tests/unit/main.cpp",
"tests/unit/ABitmapTests.cpp",
+ "tests/unit/AutoBackendTextureReleaseTests.cpp",
"tests/unit/CacheManagerTests.cpp",
"tests/unit/CanvasContextTests.cpp",
"tests/unit/CanvasOpTests.cpp",
diff --git a/libs/hwui/AutoBackendTextureRelease.cpp b/libs/hwui/AutoBackendTextureRelease.cpp
index ef5eacbdb4ad..b656b6ac8204 100644
--- a/libs/hwui/AutoBackendTextureRelease.cpp
+++ b/libs/hwui/AutoBackendTextureRelease.cpp
@@ -32,9 +32,17 @@ AutoBackendTextureRelease::AutoBackendTextureRelease(GrDirectContext* context,
bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
GrBackendFormat backendFormat =
GrAHardwareBufferUtils::GetBackendFormat(context, buffer, desc.format, false);
+ LOG_ALWAYS_FATAL_IF(!backendFormat.isValid(),
+ __FILE__ " Invalid GrBackendFormat. GrBackendApi==%" PRIu32
+ ", AHardwareBuffer_Format==%" PRIu32 ".",
+ static_cast(context->backend()), desc.format);
mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture(
context, buffer, desc.width, desc.height, &mDeleteProc, &mUpdateProc, &mImageCtx,
createProtectedImage, backendFormat, false);
+ LOG_ALWAYS_FATAL_IF(!mBackendTexture.isValid(),
+ __FILE__ " Invalid GrBackendTexture. Width==%" PRIu32 ", height==%" PRIu32
+ ", protected==%d",
+ desc.width, desc.height, createProtectedImage);
}
void AutoBackendTextureRelease::unref(bool releaseImage) {
@@ -74,13 +82,13 @@ void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer,
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
+ // The following ref will be counteracted by Skia calling releaseProc, either during
+ // MakeFromTexture if there is a failure, or later when SkImage is discarded. It must
+ // be called before MakeFromTexture, otherwise Skia may remove HWUI's ref on failure.
+ ref();
mImage = SkImage::MakeFromTexture(
context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType,
uirenderer::DataSpaceToColorSpace(dataspace), releaseProc, this);
- if (mImage.get()) {
- // The following ref will be counteracted by releaseProc, when SkImage is discarded.
- ref();
- }
}
void AutoBackendTextureRelease::newBufferContent(GrDirectContext* context) {
diff --git a/libs/hwui/AutoBackendTextureRelease.h b/libs/hwui/AutoBackendTextureRelease.h
index c9bb767a3185..f0eb2a8b6eab 100644
--- a/libs/hwui/AutoBackendTextureRelease.h
+++ b/libs/hwui/AutoBackendTextureRelease.h
@@ -25,6 +25,9 @@
namespace android {
namespace uirenderer {
+// Friend TestUtils serves as a proxy for any test cases that require access to private members.
+class TestUtils;
+
/**
* AutoBackendTextureRelease manages EglImage/VkImage lifetime. It is a ref-counted object
* that keeps GPU resources alive until the last SkImage object using them is destroyed.
@@ -66,6 +69,9 @@ class AutoBackendTextureRelease final {
// mImage is the SkImage created from mBackendTexture.
sk_sp mImage;
+
+ // Friend TestUtils serves as a proxy for any test cases that require access to private members.
+ friend class TestUtils;
};
} /* namespace uirenderer */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5092675a8104..fcaa745e9fc6 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -16,6 +16,7 @@
#pragma once
+#include
#include
#include
#include
@@ -283,6 +284,11 @@ class TestUtils {
static SkRect getClipBounds(const SkCanvas* canvas);
static SkRect getLocalClipBounds(const SkCanvas* canvas);
+ static int getUsageCount(const AutoBackendTextureRelease* textureRelease) {
+ EXPECT_NE(nullptr, textureRelease);
+ return textureRelease->mUsageCount;
+ }
+
struct CallCounts {
int sync = 0;
int contextDestroyed = 0;
diff --git a/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp b/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp
new file mode 100644
index 000000000000..2ec78a429481
--- /dev/null
+++ b/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 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 "AutoBackendTextureRelease.h"
+#include "tests/common/TestUtils.h"
+
+using namespace android;
+using namespace android::uirenderer;
+
+AHardwareBuffer* allocHardwareBuffer() {
+ AHardwareBuffer* buffer;
+ AHardwareBuffer_Desc desc = {
+ .width = 16,
+ .height = 16,
+ .layers = 1,
+ .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+ .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY,
+ };
+ constexpr int kSucceeded = 0;
+ int status = AHardwareBuffer_allocate(&desc, &buffer);
+ EXPECT_EQ(kSucceeded, status);
+ return buffer;
+}
+
+// Expands to AutoBackendTextureRelease_makeImage_invalid_RenderThreadTest,
+// set as friend in AutoBackendTextureRelease.h
+RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_invalid) {
+ AHardwareBuffer* buffer = allocHardwareBuffer();
+ AutoBackendTextureRelease* textureRelease =
+ new AutoBackendTextureRelease(renderThread.getGrContext(), buffer);
+
+ EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease));
+
+ // SkImage::MakeFromTexture should fail if given null GrDirectContext.
+ textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, /*context = */ nullptr);
+
+ EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease));
+
+ textureRelease->unref(true);
+ AHardwareBuffer_release(buffer);
+}
+
+// Expands to AutoBackendTextureRelease_makeImage_valid_RenderThreadTest,
+// set as friend in AutoBackendTextureRelease.h
+RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_valid) {
+ AHardwareBuffer* buffer = allocHardwareBuffer();
+ AutoBackendTextureRelease* textureRelease =
+ new AutoBackendTextureRelease(renderThread.getGrContext(), buffer);
+
+ EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease));
+
+ textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, renderThread.getGrContext());
+
+ EXPECT_EQ(2, TestUtils::getUsageCount(textureRelease));
+
+ textureRelease->unref(true);
+ AHardwareBuffer_release(buffer);
+}
diff --git a/media/java/android/media/AppVolume.java b/media/java/android/media/AppVolume.java
new file mode 100644
index 000000000000..fac8a02a60d5
--- /dev/null
+++ b/media/java/android/media/AppVolume.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Kaleidoscope 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.media;
+
+import android.annotation.NonNull;
+
+/**
+ * @hide
+ */
+public class AppVolume {
+ private final String mPackageName;
+ private final float mVolume;
+ private final boolean mMute;
+ private final boolean mActive;
+
+ AppVolume(String packageName, boolean mute, float volume, boolean active) {
+ mPackageName = packageName;
+ mMute = mute;
+ mVolume = volume;
+ mActive = active;
+ }
+
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public float getVolume() {
+ return mVolume;
+ }
+
+ public boolean isMuted() {
+ return mMute;
+ }
+
+ public boolean isActive() {
+ return mActive;
+ }
+}
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index ded9597b68ef..5ead6af42c6e 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -712,12 +712,6 @@ public boolean isContentSpatialized() {
*/
@CapturePolicy
public int getAllowedCapturePolicy() {
- if ((mFlags & FLAG_NO_SYSTEM_CAPTURE) == FLAG_NO_SYSTEM_CAPTURE) {
- return ALLOW_CAPTURE_BY_NONE;
- }
- if ((mFlags & FLAG_NO_MEDIA_PROJECTION) == FLAG_NO_MEDIA_PROJECTION) {
- return ALLOW_CAPTURE_BY_SYSTEM;
- }
return ALLOW_CAPTURE_BY_ALL;
}
@@ -1766,20 +1760,7 @@ private static int toVolumeStreamType(boolean fromGetVolumeControlStream, AudioA
* @hide
*/
public static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) {
- switch (capturePolicy) {
- case ALLOW_CAPTURE_BY_NONE:
- flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE;
- break;
- case ALLOW_CAPTURE_BY_SYSTEM:
- flags |= FLAG_NO_MEDIA_PROJECTION;
- flags &= ~FLAG_NO_SYSTEM_CAPTURE;
- break;
- case ALLOW_CAPTURE_BY_ALL:
- flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION;
- break;
- default:
- throw new IllegalArgumentException("Unknown allow playback capture policy");
- }
+ flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION;
return flags;
}
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index d06bbc61f6eb..2ecaf23759d9 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -355,6 +355,31 @@ public final class AudioFormat implements Parcelable {
/** Audio data format: DRA compressed */
public static final int ENCODING_DRA = 28;
+ /** Audio data format: AMRNB
+ * @hide
+ * */
+ public static final int ENCODING_AMRNB = 100;
+ /** Audio data format: AMRWB
+ * @hide
+ * */
+ public static final int ENCODING_AMRWB = 101;
+ /** Audio data format: EVRC
+ * @hide
+ * */
+ public static final int ENCODING_EVRC = 102;
+ /** Audio data format: EVRCB
+ * @hide
+ * */
+ public static final int ENCODING_EVRCB = 103;
+ /** Audio data format: EVRCWB
+ * @hide
+ * */
+ public static final int ENCODING_EVRCWB = 104;
+ /** Audio data format: EVRCNW
+ * @hide
+ * */
+ public static final int ENCODING_EVRCNW = 105;
+
/** @hide */
public static String toLogFriendlyEncoding(int enc) {
switch(enc) {
@@ -715,6 +740,7 @@ public static int convertNativeChannelMaskToOutMask(int nativeMask) {
| CHANNEL_IN_BACK_RIGHT | CHANNEL_IN_LOW_FREQUENCY);
/** @hide */
public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK;
+
// CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL
/** @hide */
@@ -733,6 +759,15 @@ public static int getBytesPerSample(int audioFormat)
case ENCODING_PCM_FLOAT:
case ENCODING_PCM_32BIT:
return 4;
+ case ENCODING_AMRNB:
+ return 32;
+ case ENCODING_AMRWB:
+ return 61;
+ case ENCODING_EVRC:
+ case ENCODING_EVRCB:
+ case ENCODING_EVRCWB:
+ case ENCODING_EVRCNW:
+ return 23;
case ENCODING_INVALID:
default:
throw new IllegalArgumentException("Bad audio format " + audioFormat);
@@ -770,6 +805,12 @@ public static boolean isValidEncoding(int audioFormat)
case ENCODING_MPEGH_LC_L4:
case ENCODING_DTS_UHD:
case ENCODING_DRA:
+ case ENCODING_AMRNB:
+ case ENCODING_AMRWB:
+ case ENCODING_EVRC:
+ case ENCODING_EVRCB:
+ case ENCODING_EVRCWB:
+ case ENCODING_EVRCNW:
return true;
default:
return false;
@@ -847,6 +888,12 @@ public static boolean isEncodingLinearPcm(int audioFormat)
case ENCODING_MPEGH_LC_L4:
case ENCODING_DTS_UHD:
case ENCODING_DRA:
+ case ENCODING_AMRNB:
+ case ENCODING_AMRWB:
+ case ENCODING_EVRC:
+ case ENCODING_EVRCB:
+ case ENCODING_EVRCWB:
+ case ENCODING_EVRCNW:
return false;
case ENCODING_INVALID:
default:
@@ -1175,6 +1222,12 @@ public Builder setEncoding(@Encoding int encoding) throws IllegalArgumentExcepti
case ENCODING_MPEGH_LC_L4:
case ENCODING_DTS_UHD:
case ENCODING_DRA:
+ case ENCODING_AMRNB:
+ case ENCODING_AMRWB:
+ case ENCODING_EVRC:
+ case ENCODING_EVRCB:
+ case ENCODING_EVRCWB:
+ case ENCODING_EVRCNW:
mEncoding = encoding;
break;
case ENCODING_INVALID:
@@ -1403,7 +1456,13 @@ public String toString () {
ENCODING_MPEGH_LC_L3,
ENCODING_MPEGH_LC_L4,
ENCODING_DTS_UHD,
- ENCODING_DRA }
+ ENCODING_DRA,
+ ENCODING_AMRNB,
+ ENCODING_AMRWB,
+ ENCODING_EVRC,
+ ENCODING_EVRCB,
+ ENCODING_EVRCWB,
+ ENCODING_EVRCNW }
)
@Retention(RetentionPolicy.SOURCE)
public @interface Encoding {}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e7eda3ea4552..4ec82723f3da 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1036,6 +1036,32 @@ public void setMasterMute(boolean mute, int flags) {
}
}
+ /** @hide */
+ @UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public int setAppVolume(String packageName, float volume) {
+ return AudioSystem.setAppVolume(packageName, volume);
+ }
+
+ /** @hide */
+ @UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public int setAppMute(String packageName, boolean mute) {
+ return AudioSystem.setAppMute(packageName, mute);
+ }
+
+ /** @hide */
+ @UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public ArrayList listAppVolumes() {
+ ArrayList volumes = new ArrayList();
+ int status = AudioSystem.listAppVolumes(volumes);
+ if (status != AudioManager.SUCCESS) {
+ return new ArrayList();
+ }
+ return volumes;
+ }
+
/**
* Returns the current ringtone mode.
*
@@ -2325,10 +2351,9 @@ private int removeOnDevRoleForCapturePresetChangedListener(
return AudioSystem.SUCCESS;
}
- private final Map mDevRoleForCapturePresetListeners = new HashMap<>(){{
- put(AudioSystem.DEVICE_ROLE_PREFERRED,
- new DevRoleListeners());
- }};
+ private final Map mDevRoleForCapturePresetListeners = Map.of(
+ AudioSystem.DEVICE_ROLE_PREFERRED,
+ new DevRoleListeners());
private class DevRoleListenerInfo {
final @NonNull Executor mExecutor;
@@ -6483,15 +6508,17 @@ public void unregisterAudioPortUpdateListener(OnAudioPortUpdateListener l) {
// AudioPort implementation
//
- static final int AUDIOPORT_GENERATION_INIT = 0;
- static Integer sAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT);
- static ArrayList sAudioPortsCached = new ArrayList();
- static ArrayList sPreviousAudioPortsCached = new ArrayList();
- static ArrayList sAudioPatchesCached = new ArrayList();
+ private static final int AUDIOPORT_GENERATION_INIT = 0;
+ private static Object sAudioPortGenerationLock = new Object();
+ @GuardedBy("sAudioPortGenerationLock")
+ private static int sAudioPortGeneration = AUDIOPORT_GENERATION_INIT;
+ private static ArrayList sAudioPortsCached = new ArrayList();
+ private static ArrayList sPreviousAudioPortsCached = new ArrayList();
+ private static ArrayList sAudioPatchesCached = new ArrayList();
static int resetAudioPortGeneration() {
int generation;
- synchronized (sAudioPortGeneration) {
+ synchronized (sAudioPortGenerationLock) {
generation = sAudioPortGeneration;
sAudioPortGeneration = AUDIOPORT_GENERATION_INIT;
}
@@ -6501,7 +6528,7 @@ static int resetAudioPortGeneration() {
static int updateAudioPortCache(ArrayList ports, ArrayList patches,
ArrayList previousPorts) {
sAudioPortEventHandler.init();
- synchronized (sAudioPortGeneration) {
+ synchronized (sAudioPortGenerationLock) {
if (sAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
int[] patchGeneration = new int[1];
diff --git a/media/java/android/media/AudioMetadata.java b/media/java/android/media/AudioMetadata.java
index ca175b4853a6..0f962f9e9d4b 100644
--- a/media/java/android/media/AudioMetadata.java
+++ b/media/java/android/media/AudioMetadata.java
@@ -30,6 +30,7 @@
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -446,14 +447,13 @@ private static Object getValueFromValuePair(@Nullable Pair, Object> value
// BaseMap is corresponding to audio_utils::metadata::Data
private static final int AUDIO_METADATA_OBJ_TYPE_BASEMAP = 6;
- private static final HashMap AUDIO_METADATA_OBJ_TYPES = new HashMap<>() {{
- put(Integer.class, AUDIO_METADATA_OBJ_TYPE_INT);
- put(Long.class, AUDIO_METADATA_OBJ_TYPE_LONG);
- put(Float.class, AUDIO_METADATA_OBJ_TYPE_FLOAT);
- put(Double.class, AUDIO_METADATA_OBJ_TYPE_DOUBLE);
- put(String.class, AUDIO_METADATA_OBJ_TYPE_STRING);
- put(BaseMap.class, AUDIO_METADATA_OBJ_TYPE_BASEMAP);
- }};
+ private static final Map AUDIO_METADATA_OBJ_TYPES = Map.of(
+ Integer.class, AUDIO_METADATA_OBJ_TYPE_INT,
+ Long.class, AUDIO_METADATA_OBJ_TYPE_LONG,
+ Float.class, AUDIO_METADATA_OBJ_TYPE_FLOAT,
+ Double.class, AUDIO_METADATA_OBJ_TYPE_DOUBLE,
+ String.class, AUDIO_METADATA_OBJ_TYPE_STRING,
+ BaseMap.class, AUDIO_METADATA_OBJ_TYPE_BASEMAP);
private static final Charset AUDIO_METADATA_CHARSET = StandardCharsets.UTF_8;
@@ -634,8 +634,8 @@ default Class getMyType() {
* Datum corresponds to Object
****************************************************************************************/
- private static final HashMap> DATA_PACKAGES = new HashMap<>() {{
- put(AUDIO_METADATA_OBJ_TYPE_INT, new DataPackage() {
+ private static final Map> DATA_PACKAGES = Map.of(
+ AUDIO_METADATA_OBJ_TYPE_INT, new DataPackage() {
@Override
@Nullable
public Integer unpack(ByteBuffer buffer) {
@@ -647,8 +647,8 @@ public boolean pack(AutoGrowByteBuffer output, Integer obj) {
output.putInt(obj);
return true;
}
- });
- put(AUDIO_METADATA_OBJ_TYPE_LONG, new DataPackage() {
+ },
+ AUDIO_METADATA_OBJ_TYPE_LONG, new DataPackage() {
@Override
@Nullable
public Long unpack(ByteBuffer buffer) {
@@ -660,8 +660,8 @@ public boolean pack(AutoGrowByteBuffer output, Long obj) {
output.putLong(obj);
return true;
}
- });
- put(AUDIO_METADATA_OBJ_TYPE_FLOAT, new DataPackage() {
+ },
+ AUDIO_METADATA_OBJ_TYPE_FLOAT, new DataPackage() {
@Override
@Nullable
public Float unpack(ByteBuffer buffer) {
@@ -673,8 +673,8 @@ public boolean pack(AutoGrowByteBuffer output, Float obj) {
output.putFloat(obj);
return true;
}
- });
- put(AUDIO_METADATA_OBJ_TYPE_DOUBLE, new DataPackage() {
+ },
+ AUDIO_METADATA_OBJ_TYPE_DOUBLE, new DataPackage() {
@Override
@Nullable
public Double unpack(ByteBuffer buffer) {
@@ -686,8 +686,8 @@ public boolean pack(AutoGrowByteBuffer output, Double obj) {
output.putDouble(obj);
return true;
}
- });
- put(AUDIO_METADATA_OBJ_TYPE_STRING, new DataPackage() {
+ },
+ AUDIO_METADATA_OBJ_TYPE_STRING, new DataPackage() {
@Override
@Nullable
public String unpack(ByteBuffer buffer) {
@@ -713,9 +713,9 @@ public boolean pack(AutoGrowByteBuffer output, String obj) {
output.put(valueArr);
return true;
}
- });
- put(AUDIO_METADATA_OBJ_TYPE_BASEMAP, new BaseMapPackage());
- }};
+ },
+ AUDIO_METADATA_OBJ_TYPE_BASEMAP, new BaseMapPackage());
+
// ObjectPackage is a special case that it is expected to unpack audio_utils::metadata::Datum,
// which contains data type and data size besides the payload for the data.
private static final ObjectPackage OBJECT_PACKAGE = new ObjectPackage();
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 8be1bcdc9479..34e8c6f21857 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1055,6 +1055,12 @@ private void audioParamCheck(int audioSource, int sampleRateInHz, int audioForma
case AudioFormat.ENCODING_PCM_FLOAT:
case AudioFormat.ENCODING_PCM_16BIT:
case AudioFormat.ENCODING_PCM_8BIT:
+ case AudioFormat.ENCODING_AMRNB:
+ case AudioFormat.ENCODING_AMRWB:
+ case AudioFormat.ENCODING_EVRC:
+ case AudioFormat.ENCODING_EVRCB:
+ case AudioFormat.ENCODING_EVRCWB:
+ case AudioFormat.ENCODING_EVRCNW:
mAudioFormat = audioFormat;
break;
default:
@@ -1298,6 +1304,9 @@ static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int au
case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
channelCount = 2;
break;
+ case AudioFormat.CHANNEL_IN_5POINT1:
+ channelCount = 6;
+ break;
case AudioFormat.CHANNEL_INVALID:
default:
loge("getMinBufferSize(): Invalid channel configuration.");
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 7ccbe51bbd49..b261f516f012 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1758,6 +1758,13 @@ public static String deviceSetToString(@NonNull Set devices) {
return sb.toString();
}
+ /** @hide */
+ public static native int setAppVolume(@NonNull String packageName, float volume);
+ /** @hide */
+ public static native int setAppMute(@NonNull String packageName, boolean mute);
+ /** @hide */
+ public static native int listAppVolumes(ArrayList volumes);
+
/**
* @hide
* Do not use directly, see {@link AudioManager#getDevicesForAttributes(AudioAttributes)}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 85cd342b5e11..d51f1e1327bd 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -48,8 +48,8 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.NioUtils;
-import java.util.HashMap;
import java.util.LinkedList;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -1867,26 +1867,24 @@ private void audioParamCheck(int sampleRateInHz, int channelConfig, int channelI
}
// General pair map
- private static final HashMap CHANNEL_PAIR_MAP = new HashMap<>() {{
- put("front", AudioFormat.CHANNEL_OUT_FRONT_LEFT
- | AudioFormat.CHANNEL_OUT_FRONT_RIGHT);
- put("back", AudioFormat.CHANNEL_OUT_BACK_LEFT
- | AudioFormat.CHANNEL_OUT_BACK_RIGHT);
- put("front of center", AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER
- | AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
- put("side", AudioFormat.CHANNEL_OUT_SIDE_LEFT
- | AudioFormat.CHANNEL_OUT_SIDE_RIGHT);
- put("top front", AudioFormat.CHANNEL_OUT_TOP_FRONT_LEFT
- | AudioFormat.CHANNEL_OUT_TOP_FRONT_RIGHT);
- put("top back", AudioFormat.CHANNEL_OUT_TOP_BACK_LEFT
- | AudioFormat.CHANNEL_OUT_TOP_BACK_RIGHT);
- put("top side", AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT
- | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT);
- put("bottom front", AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_LEFT
- | AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_RIGHT);
- put("front wide", AudioFormat.CHANNEL_OUT_FRONT_WIDE_LEFT
- | AudioFormat.CHANNEL_OUT_FRONT_WIDE_RIGHT);
- }};
+ private static final Map CHANNEL_PAIR_MAP = Map.of(
+ "front", AudioFormat.CHANNEL_OUT_FRONT_LEFT
+ | AudioFormat.CHANNEL_OUT_FRONT_RIGHT,
+ "back", AudioFormat.CHANNEL_OUT_BACK_LEFT
+ | AudioFormat.CHANNEL_OUT_BACK_RIGHT,
+ "front of center", AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER
+ | AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER,
+ "side", AudioFormat.CHANNEL_OUT_SIDE_LEFT | AudioFormat.CHANNEL_OUT_SIDE_RIGHT,
+ "top front", AudioFormat.CHANNEL_OUT_TOP_FRONT_LEFT
+ | AudioFormat.CHANNEL_OUT_TOP_FRONT_RIGHT,
+ "top back", AudioFormat.CHANNEL_OUT_TOP_BACK_LEFT
+ | AudioFormat.CHANNEL_OUT_TOP_BACK_RIGHT,
+ "top side", AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT
+ | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT,
+ "bottom front", AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_LEFT
+ | AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_RIGHT,
+ "front wide", AudioFormat.CHANNEL_OUT_FRONT_WIDE_LEFT
+ | AudioFormat.CHANNEL_OUT_FRONT_WIDE_RIGHT);
/**
* Convenience method to check that the channel configuration (a.k.a channel mask) is supported
@@ -1924,7 +1922,7 @@ private static boolean isMultichannelConfigSupported(int channelConfig, int enco
return false;
}
// Check all pairs to see that they are matched (front duplicated here).
- for (HashMap.Entry