diff options
Diffstat (limited to 'packages')
68 files changed, 1578 insertions, 951 deletions
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index 1019e6c..c7b7e6a 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -146,6 +146,7 @@ public class CaptivePortalLoginActivity extends Activity { private void done(Result result) { if (mNetworkCallback != null) { mCm.unregisterNetworkCallback(mNetworkCallback); + mNetworkCallback = null; } switch (result) { case DISMISSED: @@ -191,6 +192,16 @@ public class CaptivePortalLoginActivity extends Activity { return super.onOptionsItemSelected(item); } + @Override + public void onDestroy() { + super.onDestroy(); + + if (mNetworkCallback != null) { + mCm.unregisterNetworkCallback(mNetworkCallback); + mNetworkCallback = null; + } + } + private void testForCaptivePortal() { new Thread(new Runnable() { public void run() { diff --git a/packages/DocumentsUI/res/layout/fragment_pick.xml b/packages/DocumentsUI/res/layout/fragment_pick.xml index 87dc4f8..40d4eb5 100644 --- a/packages/DocumentsUI/res/layout/fragment_pick.xml +++ b/packages/DocumentsUI/res/layout/fragment_pick.xml @@ -19,13 +19,13 @@ android:layout_height="wrap_content" android:orientation="horizontal" android:baselineAligned="false" - android:gravity="center_vertical" + android:gravity="end" + android:paddingEnd="8dp" android:minHeight="?android:attr/listPreferredItemHeightSmall"> <Button android:id="@android:id/button2" android:layout_width="wrap_content" android:layout_height="match_parent" - android:layout_weight="1" android:text="@android:string/cancel" android:visibility="gone" style="?android:attr/buttonBarNegativeButtonStyle" /> @@ -33,7 +33,5 @@ android:id="@android:id/button1" android:layout_width="wrap_content" android:layout_height="match_parent" - android:layout_weight="1" - android:textAllCaps="false" style="?android:attr/buttonBarPositiveButtonStyle" /> </LinearLayout> diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml index 5281087..9794273 100644 --- a/packages/DocumentsUI/res/values/strings.xml +++ b/packages/DocumentsUI/res/values/strings.xml @@ -44,8 +44,6 @@ <string name="menu_share">Share</string> <!-- Menu item title that deletes the selected documents [CHAR LIMIT=24] --> <string name="menu_delete">Delete</string> - <!-- Menu item title that selects the current directory [CHAR LIMIT=48] --> - <string name="menu_select">Select \"<xliff:g id="directory" example="My Directory">^1</xliff:g>\"</string> <!-- Menu item title that selects all documents in the current directory [CHAR LIMIT=24] --> <string name="menu_select_all">Select All</string> <!-- Menu item title that copies the selected documents [CHAR LIMIT=24] --> @@ -65,7 +63,9 @@ <!-- Menu item that hides the sizes of displayed files [CHAR LIMIT=24] --> <string name="menu_file_size_hide">Hide file size</string> - <!-- Button label that copies files to the current directory [CHAR LIMIT=48] --> + <!-- Button label that select the current directory [CHAR LIMIT=24] --> + <string name="button_select">Select</string> + <!-- Button label that copies files to the current directory [CHAR LIMIT=24] --> <string name="button_copy">Copy</string> <!-- Action mode title summarizing the number of documents selected [CHAR LIMIT=32] --> diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index cded717..8482438 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -571,9 +571,7 @@ public class DocumentsActivity extends BaseActivity { mState.action == ACTION_OPEN_COPY_DESTINATION) { final PickFragment pick = PickFragment.get(fm); if (pick != null) { - final CharSequence displayName = (mState.stack.size() <= 1) ? root.title - : cwd.displayName; - pick.setPickTarget(mState.action, cwd, displayName); + pick.setPickTarget(mState.action, cwd); } } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java index e899379..d9b8568 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java @@ -38,15 +38,19 @@ import java.util.Locale; public class PickFragment extends Fragment { public static final String TAG = "PickFragment"; + private int mAction; private DocumentInfo mPickTarget; - private View mContainer; private Button mPick; private Button mCancel; public static void show(FragmentManager fm) { - final PickFragment fragment = new PickFragment(); + // Fragment can be restored by FragmentManager automatically. + if (get(fm) != null) { + return; + } + final PickFragment fragment = new PickFragment(); final FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.container_save, fragment, TAG); ft.commitAllowingStateLoss(); @@ -67,8 +71,7 @@ public class PickFragment extends Fragment { mCancel = (Button) mContainer.findViewById(android.R.id.button2); mCancel.setOnClickListener(mCancelListener); - setPickTarget(0, null, null); - + updateView(); return mContainer; } @@ -92,32 +95,38 @@ public class PickFragment extends Fragment { /** * @param action Which action defined in BaseActivity.State is the picker shown for. */ - public void setPickTarget(int action, - DocumentInfo pickTarget, - CharSequence displayName) { + public void setPickTarget(int action, DocumentInfo pickTarget) { + mAction = action; + mPickTarget = pickTarget; if (mContainer != null) { - if (pickTarget != null) { - final Locale locale = getResources().getConfiguration().locale; - switch (action) { - case BaseActivity.State.ACTION_OPEN_TREE: - final String raw = getString(R.string.menu_select).toUpperCase(locale); - mPick.setText(TextUtils.expandTemplate(raw, displayName)); - mCancel.setVisibility(View.GONE); - break; - case BaseActivity.State.ACTION_OPEN_COPY_DESTINATION: - mPick.setText(getString(R.string.button_copy).toUpperCase(locale)); - mCancel.setVisibility(View.VISIBLE); - break; - default: - throw new IllegalArgumentException("Illegal action for PickFragment."); - } - } - if (pickTarget != null && pickTarget.isCreateSupported()) { - mContainer.setVisibility(View.VISIBLE); - } else { + updateView(); + } + } + + /** + * Applies the state of fragment to the view components. + */ + private void updateView() { + switch (mAction) { + case BaseActivity.State.ACTION_OPEN_TREE: + mPick.setText(R.string.button_select); + mCancel.setVisibility(View.GONE); + break; + case BaseActivity.State.ACTION_OPEN_COPY_DESTINATION: + mPick.setText(R.string.button_copy); + mCancel.setVisibility(View.VISIBLE); + break; + default: mContainer.setVisibility(View.GONE); - } + return; + } + + if (mPickTarget != null && ( + mAction == BaseActivity.State.ACTION_OPEN_TREE || + mPickTarget.isCreateSupported())) { + mContainer.setVisibility(View.VISIBLE); + } else { + mContainer.setVisibility(View.GONE); } - mPickTarget = pickTarget; } } diff --git a/packages/Keyguard/res/values-h650dp/dimens.xml b/packages/Keyguard/res/values-h650dp/dimens.xml index 92035bb..1cd2162 100644 --- a/packages/Keyguard/res/values-h650dp/dimens.xml +++ b/packages/Keyguard/res/values-h650dp/dimens.xml @@ -16,5 +16,5 @@ --> <resources> - <dimen name="widget_big_font_size">104dp</dimen> + <dimen name="widget_big_font_size">100dp</dimen> </resources>
\ No newline at end of file diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java index 1cabcdf..e03f449 100644 --- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java +++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java @@ -16,6 +16,7 @@ package com.android.keyguard; +import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -42,7 +43,7 @@ public class EmergencyButton extends Button { .setPackage("com.android.phone") .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS - | Intent.FLAG_ACTIVITY_CLEAR_TASK); + | Intent.FLAG_ACTIVITY_CLEAR_TOP); KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { @@ -127,6 +128,7 @@ public class EmergencyButton extends Button { KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction( true /* bypassHandler */); getContext().startActivityAsUser(INTENT_EMERGENCY_DIAL, + ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(), new UserHandle(KeyguardUpdateMonitor.getCurrentUser())); } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java index 3fcc3c3..f18c451 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java @@ -35,6 +35,8 @@ import android.view.inputmethod.InputMethodSubtype; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; +import com.android.internal.widget.TextViewInputDisabler; + import java.util.List; /** * Displays an alphanumeric (latin-1) key entry for the user to enter @@ -49,6 +51,8 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView InputMethodManager mImm; private TextView mPasswordEntry; + private TextViewInputDisabler mPasswordEntryDisabler; + private Interpolator mLinearOutSlowInInterpolator; private Interpolator mFastOutLinearInInterpolator; @@ -70,7 +74,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView protected void resetState() { mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false); - mPasswordEntry.setEnabled(true); + setPasswordEntryEnabled(true); } @Override @@ -123,6 +127,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView Context.INPUT_METHOD_SERVICE); mPasswordEntry = (TextView) findViewById(getPasswordTextViewId()); + mPasswordEntryDisabler = new TextViewInputDisabler(mPasswordEntry); mPasswordEntry.setKeyListener(TextKeyListener.getInstance()); mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); @@ -185,7 +190,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView @Override protected void setPasswordEntryEnabled(boolean enabled) { - mPasswordEntry.setEnabled(enabled); + mPasswordEntryDisabler.setInputEnabled(enabled); } /** diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 5fece8d..5360645 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -361,9 +361,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId); return; } - if (groupId == userId) { - onFingerprintAuthenticated(groupId); - } + onFingerprintAuthenticated(userId); } finally { setFingerprintRunningDetectionRunning(false); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 5d6b2f1..d3e7104 100755 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -51,11 +51,13 @@ public final class BluetoothEventManager { private final Collection<BluetoothCallback> mCallbacks = new ArrayList<BluetoothCallback>(); + private android.os.Handler mReceiverHandler; + interface Handler { void onReceive(Context context, Intent intent, BluetoothDevice device); } - void addHandler(String action, Handler handler) { + private void addHandler(String action, Handler handler) { mHandlerMap.put(action, handler); mAdapterIntentFilter.addAction(action); } @@ -103,11 +105,18 @@ public final class BluetoothEventManager { // Dock event broadcasts addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler()); - mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter); + mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler); } void registerProfileIntentReceiver() { - mContext.registerReceiver(mBroadcastReceiver, mProfileIntentFilter); + mContext.registerReceiver(mBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler); + } + + public void setReceiverHandler(android.os.Handler handler) { + mContext.unregisterReceiver(mBroadcastReceiver); + mReceiverHandler = handler; + mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler); + registerProfileIntentReceiver(); } /** Register to start receiving callbacks for Bluetooth events. */ diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index ad710a6..1dba942 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -201,14 +201,14 @@ public class SettingsProvider extends ContentProvider { @GuardedBy("mLock") private SettingsRegistry mSettingsRegistry; - @GuardedBy("mLock") - private UserManager mUserManager; + // We have to call in the user manager with no lock held, + private volatile UserManager mUserManager; - @GuardedBy("mLock") - private AppOpsManager mAppOpsManager; + // We have to call in the app ops manager with no lock held, + private volatile AppOpsManager mAppOpsManager; - @GuardedBy("mLock") - private PackageManager mPackageManager; + // We have to call in the package manager with no lock held, + private volatile PackageManager mPackageManager; @Override public boolean onCreate() { @@ -224,44 +224,46 @@ public class SettingsProvider extends ContentProvider { @Override public Bundle call(String method, String name, Bundle args) { - synchronized (mLock) { - final int requestingUserId = getRequestingUserId(args); - switch (method) { - case Settings.CALL_METHOD_GET_GLOBAL: { - Setting setting = getGlobalSettingLocked(name); - return packageValueForCallResult(setting); - } - - case Settings.CALL_METHOD_GET_SECURE: { - Setting setting = getSecureSettingLocked(name, requestingUserId); - return packageValueForCallResult(setting); - } + final int requestingUserId = getRequestingUserId(args); + switch (method) { + case Settings.CALL_METHOD_GET_GLOBAL: { + Setting setting = getGlobalSetting(name); + return packageValueForCallResult(setting); + } - case Settings.CALL_METHOD_GET_SYSTEM: { - Setting setting = getSystemSettingLocked(name, requestingUserId); - return packageValueForCallResult(setting); - } + case Settings.CALL_METHOD_GET_SECURE: { + Setting setting = getSecureSetting(name, requestingUserId); + return packageValueForCallResult(setting); + } - case Settings.CALL_METHOD_PUT_GLOBAL: { - String value = getSettingValue(args); - insertGlobalSettingLocked(name, value, requestingUserId); - } break; + case Settings.CALL_METHOD_GET_SYSTEM: { + Setting setting = getSystemSetting(name, requestingUserId); + return packageValueForCallResult(setting); + } - case Settings.CALL_METHOD_PUT_SECURE: { - String value = getSettingValue(args); - insertSecureSettingLocked(name, value, requestingUserId); - } break; + case Settings.CALL_METHOD_PUT_GLOBAL: { + String value = getSettingValue(args); + insertGlobalSetting(name, value, requestingUserId); + break; + } - case Settings.CALL_METHOD_PUT_SYSTEM: { - String value = getSettingValue(args); - insertSystemSettingLocked(name, value, requestingUserId); - } break; + case Settings.CALL_METHOD_PUT_SECURE: { + String value = getSettingValue(args); + insertSecureSetting(name, value, requestingUserId); + break; + } - default: { - Slog.w(LOG_TAG, "call() with invalid method: " + method); - } break; + case Settings.CALL_METHOD_PUT_SYSTEM: { + String value = getSettingValue(args); + insertSystemSetting(name, value, requestingUserId); + break; } + + default: { + Slog.w(LOG_TAG, "call() with invalid method: " + method); + } break; } + return null; } @@ -271,7 +273,7 @@ public class SettingsProvider extends ContentProvider { if (TextUtils.isEmpty(args.name)) { return "vnd.android.cursor.dir/" + args.table; } else { - return "vnd.android.cursor.item/" + args.table; + return "vnd.android.cursor.item/" + args.table; } } @@ -290,40 +292,38 @@ public class SettingsProvider extends ContentProvider { return new MatrixCursor(normalizedProjection, 0); } - synchronized (mLock) { - switch (args.table) { - case TABLE_GLOBAL: { - if (args.name != null) { - Setting setting = getGlobalSettingLocked(args.name); - return packageSettingForQuery(setting, normalizedProjection); - } else { - return getAllGlobalSettingsLocked(projection); - } + switch (args.table) { + case TABLE_GLOBAL: { + if (args.name != null) { + Setting setting = getGlobalSetting(args.name); + return packageSettingForQuery(setting, normalizedProjection); + } else { + return getAllGlobalSettings(projection); } + } - case TABLE_SECURE: { - final int userId = UserHandle.getCallingUserId(); - if (args.name != null) { - Setting setting = getSecureSettingLocked(args.name, userId); - return packageSettingForQuery(setting, normalizedProjection); - } else { - return getAllSecureSettingsLocked(userId, projection); - } + case TABLE_SECURE: { + final int userId = UserHandle.getCallingUserId(); + if (args.name != null) { + Setting setting = getSecureSetting(args.name, userId); + return packageSettingForQuery(setting, normalizedProjection); + } else { + return getAllSecureSettings(userId, projection); } + } - case TABLE_SYSTEM: { - final int userId = UserHandle.getCallingUserId(); - if (args.name != null) { - Setting setting = getSystemSettingLocked(args.name, userId); - return packageSettingForQuery(setting, normalizedProjection); - } else { - return getAllSystemSettingsLocked(userId, projection); - } + case TABLE_SYSTEM: { + final int userId = UserHandle.getCallingUserId(); + if (args.name != null) { + Setting setting = getSystemSetting(args.name, userId); + return packageSettingForQuery(setting, normalizedProjection); + } else { + return getAllSystemSettings(userId, projection); } + } - default: { - throw new IllegalArgumentException("Invalid Uri path:" + uri); - } + default: { + throw new IllegalArgumentException("Invalid Uri path:" + uri); } } } @@ -348,29 +348,27 @@ public class SettingsProvider extends ContentProvider { String value = values.getAsString(Settings.Secure.VALUE); - synchronized (mLock) { - switch (table) { - case TABLE_GLOBAL: { - if (insertGlobalSettingLocked(name, value, UserHandle.getCallingUserId())) { - return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name); - } - } break; - - case TABLE_SECURE: { - if (insertSecureSettingLocked(name, value, UserHandle.getCallingUserId())) { - return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name); - } - } break; + switch (table) { + case TABLE_GLOBAL: { + if (insertGlobalSetting(name, value, UserHandle.getCallingUserId())) { + return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name); + } + } break; - case TABLE_SYSTEM: { - if (insertSystemSettingLocked(name, value, UserHandle.getCallingUserId())) { - return Uri.withAppendedPath(Settings.System.CONTENT_URI, name); - } - } break; + case TABLE_SECURE: { + if (insertSecureSetting(name, value, UserHandle.getCallingUserId())) { + return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name); + } + } break; - default: { - throw new IllegalArgumentException("Bad Uri path:" + uri); + case TABLE_SYSTEM: { + if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) { + return Uri.withAppendedPath(Settings.System.CONTENT_URI, name); } + } break; + + default: { + throw new IllegalArgumentException("Bad Uri path:" + uri); } } @@ -412,26 +410,25 @@ public class SettingsProvider extends ContentProvider { return 0; } - synchronized (mLock) { - switch (args.table) { - case TABLE_GLOBAL: { - final int userId = UserHandle.getCallingUserId(); - return deleteGlobalSettingLocked(args.name, userId) ? 1 : 0; - } - case TABLE_SECURE: { - final int userId = UserHandle.getCallingUserId(); - return deleteSecureSettingLocked(args.name, userId) ? 1 : 0; - } + switch (args.table) { + case TABLE_GLOBAL: { + final int userId = UserHandle.getCallingUserId(); + return deleteGlobalSetting(args.name, userId) ? 1 : 0; + } - case TABLE_SYSTEM: { - final int userId = UserHandle.getCallingUserId(); - return deleteSystemSettingLocked(args.name, userId) ? 1 : 0; - } + case TABLE_SECURE: { + final int userId = UserHandle.getCallingUserId(); + return deleteSecureSetting(args.name, userId) ? 1 : 0; + } - default: { - throw new IllegalArgumentException("Bad Uri path:" + uri); - } + case TABLE_SYSTEM: { + final int userId = UserHandle.getCallingUserId(); + return deleteSystemSetting(args.name, userId) ? 1 : 0; + } + + default: { + throw new IllegalArgumentException("Bad Uri path:" + uri); } } } @@ -454,26 +451,24 @@ public class SettingsProvider extends ContentProvider { return 0; } - synchronized (mLock) { - switch (args.table) { - case TABLE_GLOBAL: { - final int userId = UserHandle.getCallingUserId(); - return updateGlobalSettingLocked(args.name, value, userId) ? 1 : 0; - } + switch (args.table) { + case TABLE_GLOBAL: { + final int userId = UserHandle.getCallingUserId(); + return updateGlobalSetting(args.name, value, userId) ? 1 : 0; + } - case TABLE_SECURE: { - final int userId = UserHandle.getCallingUserId(); - return updateSecureSettingLocked(args.name, value, userId) ? 1 : 0; - } + case TABLE_SECURE: { + final int userId = UserHandle.getCallingUserId(); + return updateSecureSetting(args.name, value, userId) ? 1 : 0; + } - case TABLE_SYSTEM: { - final int userId = UserHandle.getCallingUserId(); - return updateSystemSettingLocked(args.name, value, userId) ? 1 : 0; - } + case TABLE_SYSTEM: { + final int userId = UserHandle.getCallingUserId(); + return updateSystemSetting(args.name, value, userId) ? 1 : 0; + } - default: { - throw new IllegalArgumentException("Invalid Uri path:" + uri); - } + default: { + throw new IllegalArgumentException("Invalid Uri path:" + uri); } } } @@ -504,18 +499,18 @@ public class SettingsProvider extends ContentProvider { private void dumpForUser(int userId, PrintWriter pw) { if (userId == UserHandle.USER_OWNER) { pw.println("GLOBAL SETTINGS (user " + userId + ")"); - Cursor globalCursor = getAllGlobalSettingsLocked(ALL_COLUMNS); + Cursor globalCursor = getAllGlobalSettings(ALL_COLUMNS); dumpSettings(globalCursor, pw); pw.println(); } pw.println("SECURE SETTINGS (user " + userId + ")"); - Cursor secureCursor = getAllSecureSettingsLocked(userId, ALL_COLUMNS); + Cursor secureCursor = getAllSecureSettings(userId, ALL_COLUMNS); dumpSettings(secureCursor, pw); pw.println(); pw.println("SYSTEM SETTINGS (user " + userId + ")"); - Cursor systemCursor = getAllSystemSettingsLocked(userId, ALL_COLUMNS); + Cursor systemCursor = getAllSystemSettings(userId, ALL_COLUMNS); dumpSettings(systemCursor, pw); pw.println(); } @@ -575,64 +570,68 @@ public class SettingsProvider extends ContentProvider { UserHandle.ALL, true); } - private Cursor getAllGlobalSettingsLocked(String[] projection) { + private Cursor getAllGlobalSettings(String[] projection) { if (DEBUG) { - Slog.v(LOG_TAG, "getAllGlobalSettingsLocked()"); + Slog.v(LOG_TAG, "getAllGlobalSettings()"); } - // Get the settings. - SettingsState settingsState = mSettingsRegistry.getSettingsLocked( - SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER); + synchronized (mLock) { + // Get the settings. + SettingsState settingsState = mSettingsRegistry.getSettingsLocked( + SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER); - List<String> names = settingsState.getSettingNamesLocked(); + List<String> names = settingsState.getSettingNamesLocked(); - final int nameCount = names.size(); + final int nameCount = names.size(); - String[] normalizedProjection = normalizeProjection(projection); - MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); + String[] normalizedProjection = normalizeProjection(projection); + MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); - // Anyone can get the global settings, so no security checks. - for (int i = 0; i < nameCount; i++) { - String name = names.get(i); - Setting setting = settingsState.getSettingLocked(name); - appendSettingToCursor(result, setting); - } + // Anyone can get the global settings, so no security checks. + for (int i = 0; i < nameCount; i++) { + String name = names.get(i); + Setting setting = settingsState.getSettingLocked(name); + appendSettingToCursor(result, setting); + } - return result; + return result; + } } - private Setting getGlobalSettingLocked(String name) { + private Setting getGlobalSetting(String name) { if (DEBUG) { Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")"); } // Get the value. - return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, - UserHandle.USER_OWNER, name); + synchronized (mLock) { + return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, + UserHandle.USER_OWNER, name); + } } - private boolean updateGlobalSettingLocked(String name, String value, int requestingUserId) { + private boolean updateGlobalSetting(String name, String value, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "updateGlobalSettingLocked(" + name + ", " + value + ")"); + Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ")"); } - return mutateGlobalSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); + return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); } - private boolean insertGlobalSettingLocked(String name, String value, int requestingUserId) { + private boolean insertGlobalSetting(String name, String value, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "insertGlobalSettingLocked(" + name + ", " + value + ")"); + Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ")"); } - return mutateGlobalSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT); + return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT); } - private boolean deleteGlobalSettingLocked(String name, int requestingUserId) { + private boolean deleteGlobalSetting(String name, int requestingUserId) { if (DEBUG) { Slog.v(LOG_TAG, "deleteGlobalSettingLocked(" + name + ")"); } - return mutateGlobalSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE); + return mutateGlobalSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE); } - private boolean mutateGlobalSettingLocked(String name, String value, int requestingUserId, + private boolean mutateGlobalSetting(String name, String value, int requestingUserId, int operation) { // Make sure the caller can change the settings - treated as secure. enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); @@ -651,28 +650,32 @@ public class SettingsProvider extends ContentProvider { } // Perform the mutation. - switch (operation) { - case MUTATION_OPERATION_INSERT: { - return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, - UserHandle.USER_OWNER, name, value, getCallingPackage()); - } + synchronized (mLock) { + switch (operation) { + case MUTATION_OPERATION_INSERT: { + return mSettingsRegistry + .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, + UserHandle.USER_OWNER, name, value, getCallingPackage()); + } - case MUTATION_OPERATION_DELETE: { - return mSettingsRegistry.deleteSettingLocked( - SettingsRegistry.SETTINGS_TYPE_GLOBAL, - UserHandle.USER_OWNER, name); - } + case MUTATION_OPERATION_DELETE: { + return mSettingsRegistry.deleteSettingLocked( + SettingsRegistry.SETTINGS_TYPE_GLOBAL, + UserHandle.USER_OWNER, name); + } - case MUTATION_OPERATION_UPDATE: { - return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, - UserHandle.USER_OWNER, name, value, getCallingPackage()); + case MUTATION_OPERATION_UPDATE: { + return mSettingsRegistry + .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, + UserHandle.USER_OWNER, name, value, getCallingPackage()); + } } } return false; } - private Cursor getAllSecureSettingsLocked(int userId, String[] projection) { + private Cursor getAllSecureSettings(int userId, String[] projection) { if (DEBUG) { Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")"); } @@ -680,34 +683,36 @@ public class SettingsProvider extends ContentProvider { // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId); - List<String> names = mSettingsRegistry.getSettingsNamesLocked( - SettingsRegistry.SETTINGS_TYPE_SECURE, callingUserId); + synchronized (mLock) { + List<String> names = mSettingsRegistry.getSettingsNamesLocked( + SettingsRegistry.SETTINGS_TYPE_SECURE, callingUserId); - final int nameCount = names.size(); + final int nameCount = names.size(); - String[] normalizedProjection = normalizeProjection(projection); - MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); + String[] normalizedProjection = normalizeProjection(projection); + MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); - for (int i = 0; i < nameCount; i++) { - String name = names.get(i); + for (int i = 0; i < nameCount; i++) { + String name = names.get(i); + // Determine the owning user as some profile settings are cloned from the parent. + final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, + name); - // Determine the owning user as some profile settings are cloned from the parent. - final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name); + // Special case for location (sigh). + if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) { + return null; + } - // Special case for location (sigh). - if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) { - return null; + Setting setting = mSettingsRegistry.getSettingLocked( + SettingsRegistry.SETTINGS_TYPE_SECURE, owningUserId, name); + appendSettingToCursor(result, setting); } - Setting setting = mSettingsRegistry.getSettingLocked( - SettingsRegistry.SETTINGS_TYPE_SECURE, owningUserId, name); - appendSettingToCursor(result, setting); + return result; } - - return result; } - private Setting getSecureSettingLocked(String name, int requestingUserId) { + private Setting getSecureSetting(String name, int requestingUserId) { if (DEBUG) { Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")"); } @@ -724,37 +729,39 @@ public class SettingsProvider extends ContentProvider { } // Get the value. - return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, - owningUserId, name); + synchronized (mLock) { + return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, + owningUserId, name); + } } - private boolean insertSecureSettingLocked(String name, String value, int requestingUserId) { + private boolean insertSecureSetting(String name, String value, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "insertSecureSettingLocked(" + name + ", " + value + ", " + Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", " + requestingUserId + ")"); } - return mutateSecureSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT); + return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT); } - private boolean deleteSecureSettingLocked(String name, int requestingUserId) { + private boolean deleteSecureSetting(String name, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "deleteSecureSettingLocked(" + name + ", " + requestingUserId + ")"); + Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId + ")"); } - return mutateSecureSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE); + return mutateSecureSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE); } - private boolean updateSecureSettingLocked(String name, String value, int requestingUserId) { + private boolean updateSecureSetting(String name, String value, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "updateSecureSettingLocked(" + name + ", " + value + ", " + Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", " + requestingUserId + ")"); } - return mutateSecureSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); + return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); } - private boolean mutateSecureSettingLocked(String name, String value, int requestingUserId, + private boolean mutateSecureSetting(String name, String value, int requestingUserId, int operation) { // Make sure the caller can change the settings. enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); @@ -786,58 +793,65 @@ public class SettingsProvider extends ContentProvider { } // Mutate the value. - switch(operation) { - case MUTATION_OPERATION_INSERT: { - return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, - owningUserId, name, value, getCallingPackage()); - } + synchronized (mLock) { + switch (operation) { + case MUTATION_OPERATION_INSERT: { + return mSettingsRegistry + .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, + owningUserId, name, value, getCallingPackage()); + } - case MUTATION_OPERATION_DELETE: { - return mSettingsRegistry.deleteSettingLocked( - SettingsRegistry.SETTINGS_TYPE_SECURE, - owningUserId, name); - } + case MUTATION_OPERATION_DELETE: { + return mSettingsRegistry.deleteSettingLocked( + SettingsRegistry.SETTINGS_TYPE_SECURE, + owningUserId, name); + } - case MUTATION_OPERATION_UPDATE: { - return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, - owningUserId, name, value, getCallingPackage()); + case MUTATION_OPERATION_UPDATE: { + return mSettingsRegistry + .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, + owningUserId, name, value, getCallingPackage()); + } } } return false; } - private Cursor getAllSystemSettingsLocked(int userId, String[] projection) { + private Cursor getAllSystemSettings(int userId, String[] projection) { if (DEBUG) { - Slog.v(LOG_TAG, "getAllSecureSystemLocked(" + userId + ")"); + Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")"); } // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId); - List<String> names = mSettingsRegistry.getSettingsNamesLocked( - SettingsRegistry.SETTINGS_TYPE_SYSTEM, callingUserId); + synchronized (mLock) { + List<String> names = mSettingsRegistry.getSettingsNamesLocked( + SettingsRegistry.SETTINGS_TYPE_SYSTEM, callingUserId); - final int nameCount = names.size(); + final int nameCount = names.size(); - String[] normalizedProjection = normalizeProjection(projection); - MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); + String[] normalizedProjection = normalizeProjection(projection); + MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); - for (int i = 0; i < nameCount; i++) { - String name = names.get(i); + for (int i = 0; i < nameCount; i++) { + String name = names.get(i); - // Determine the owning user as some profile settings are cloned from the parent. - final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name); + // Determine the owning user as some profile settings are cloned from the parent. + final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, + name); - Setting setting = mSettingsRegistry.getSettingLocked( - SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name); - appendSettingToCursor(result, setting); - } + Setting setting = mSettingsRegistry.getSettingLocked( + SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name); + appendSettingToCursor(result, setting); + } - return result; + return result; + } } - private Setting getSystemSettingLocked(String name, int requestingUserId) { + private Setting getSystemSetting(String name, int requestingUserId) { if (DEBUG) { Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")"); } @@ -849,37 +863,39 @@ public class SettingsProvider extends ContentProvider { final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name); // Get the value. - return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, - owningUserId, name); + synchronized (mLock) { + return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, + owningUserId, name); + } } - private boolean insertSystemSettingLocked(String name, String value, int requestingUserId) { + private boolean insertSystemSetting(String name, String value, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "insertSystemSettingLocked(" + name + ", " + value + ", " + Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", " + requestingUserId + ")"); } - return mutateSystemSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT); + return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT); } - private boolean deleteSystemSettingLocked(String name, int requestingUserId) { + private boolean deleteSystemSetting(String name, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "deleteSystemSettingLocked(" + name + ", " + requestingUserId + ")"); + Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")"); } - return mutateSystemSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE); + return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE); } - private boolean updateSystemSettingLocked(String name, String value, int requestingUserId) { + private boolean updateSystemSetting(String name, String value, int requestingUserId) { if (DEBUG) { - Slog.v(LOG_TAG, "updateSystemSettingLocked(" + name + ", " + value + ", " + Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", " + requestingUserId + ")"); } - return mutateSystemSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); + return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); } - private boolean mutateSystemSettingLocked(String name, String value, int runAsUserId, + private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) { // Make sure the caller can change the settings. enforceWritePermission(Manifest.permission.WRITE_SETTINGS); @@ -904,27 +920,31 @@ public class SettingsProvider extends ContentProvider { } // Mutate the value. - switch (operation) { - case MUTATION_OPERATION_INSERT: { - validateSystemSettingValue(name, value); - return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, - owningUserId, name, value, getCallingPackage()); - } + synchronized (mLock) { + switch (operation) { + case MUTATION_OPERATION_INSERT: { + validateSystemSettingValue(name, value); + return mSettingsRegistry + .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, + owningUserId, name, value, getCallingPackage()); + } - case MUTATION_OPERATION_DELETE: { - return mSettingsRegistry.deleteSettingLocked( - SettingsRegistry.SETTINGS_TYPE_SYSTEM, - owningUserId, name); - } + case MUTATION_OPERATION_DELETE: { + return mSettingsRegistry.deleteSettingLocked( + SettingsRegistry.SETTINGS_TYPE_SYSTEM, + owningUserId, name); + } - case MUTATION_OPERATION_UPDATE: { - validateSystemSettingValue(name, value); - return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, - owningUserId, name, value, getCallingPackage()); + case MUTATION_OPERATION_UPDATE: { + validateSystemSettingValue(name, value); + return mSettingsRegistry + .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, + owningUserId, name, value, getCallingPackage()); + } } - } - return false; + return false; + } } private void validateSystemSettingValue(String name, String value) { @@ -1043,6 +1063,7 @@ public class SettingsProvider extends ContentProvider { // user info is a cached instance, so just look up instead of cache. final long identity = Binder.clearCallingIdentity(); try { + // Just a lookup and not reentrant, so holding a lock is fine. UserInfo userInfo = mUserManager.getProfileParent(userId); return (userInfo != null) ? userInfo.id : userId; } finally { @@ -1088,7 +1109,7 @@ public class SettingsProvider extends ContentProvider { // skip prefix value = value.substring(1); - Setting settingValue = getSecureSettingLocked( + Setting settingValue = getSecureSetting( Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId); String oldProviders = (settingValue != null) ? settingValue.getValue() : ""; diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index dda9358..fd0ba73 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -95,6 +95,8 @@ <uses-permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/> <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.CHANGE_APP_IDLE_STATE" /> + <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> + <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> <application android:label="@string/app_label"> <provider diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java b/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java index e71cf54..bb6bdbb 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/AbstractAsset.java @@ -63,4 +63,10 @@ public abstract class AbstractAsset { throws AssociationServiceException { return AssetFactory.create(assetJson); } + + /** + * If this is the source asset of a statement file, should the retriever follow + * any insecure (non-HTTPS) include statements made by the asset. + */ + public abstract boolean followInsecureInclude(); } diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java b/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java index 0c96038..8ead90b 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/AndroidAppAsset.java @@ -99,6 +99,12 @@ import java.util.Locale; return getPackageName().hashCode(); } + @Override + public boolean followInsecureInclude() { + // Non-HTTPS includes are not allowed in Android App assets. + return false; + } + /** * Checks that the input is a valid Android app asset. * diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java index 6516516..548149e 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java @@ -136,7 +136,8 @@ import java.util.List; } } - private Result retrieveStatementFromUrl(String url, int maxIncludeLevel, AbstractAsset source) + private Result retrieveStatementFromUrl(String urlString, int maxIncludeLevel, + AbstractAsset source) throws AssociationServiceException { List<Statement> statements = new ArrayList<Statement>(); if (maxIncludeLevel < 0) { @@ -145,7 +146,12 @@ import java.util.List; WebContent webContent; try { - webContent = mUrlFetcher.getWebContentFromUrl(new URL(url), + URL url = new URL(urlString); + if (!source.followInsecureInclude() + && !url.getProtocol().toLowerCase().equals("https")) { + return Result.create(statements, DO_NOT_CACHE_RESULT); + } + webContent = mUrlFetcher.getWebContentFromUrl(url, HTTP_CONTENT_SIZE_LIMIT_IN_BYTES, HTTP_CONNECTION_TIMEOUT_MILLIS); } catch (IOException e) { return Result.create(statements, DO_NOT_CACHE_RESULT); diff --git a/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java b/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java index 4828ff9..969aa88 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java @@ -16,6 +16,8 @@ package com.android.statementservice.retriever; +import android.util.Log; + import com.android.volley.Cache; import com.android.volley.NetworkResponse; import com.android.volley.toolbox.HttpHeaderParser; @@ -39,6 +41,7 @@ import java.util.Map; * @hide */ public class URLFetcher { + private static final String TAG = URLFetcher.class.getSimpleName(); private static final long DO_NOT_CACHE_RESULT = 0L; private static final int INPUT_BUFFER_SIZE_IN_BYTES = 1024; @@ -63,11 +66,17 @@ public class URLFetcher { connection.setConnectTimeout(connectionTimeoutMillis); connection.setReadTimeout(connectionTimeoutMillis); connection.setUseCaches(true); + connection.setInstanceFollowRedirects(false); connection.addRequestProperty("Cache-Control", "max-stale=60"); + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + Log.e(TAG, "The responses code is not 200 but " + connection.getResponseCode()); + return new WebContent("", DO_NOT_CACHE_RESULT); + } + if (connection.getContentLength() > fileSizeLimit) { - throw new AssociationServiceException("The content size of the url is larger than " - + fileSizeLimit); + Log.e(TAG, "The content size of the url is larger than " + fileSizeLimit); + return new WebContent("", DO_NOT_CACHE_RESULT); } Long expireTimeMillis = getExpirationTimeMillisFromHTTPHeader(connection.getHeaderFields()); diff --git a/packages/StatementService/src/com/android/statementservice/retriever/Utils.java b/packages/StatementService/src/com/android/statementservice/retriever/Utils.java index 44af864..afb4c75 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/Utils.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/Utils.java @@ -61,7 +61,7 @@ public final class Utils { */ public static final String ASSET_DESCRIPTOR_FIELD_RELATION = "relation"; public static final String ASSET_DESCRIPTOR_FIELD_TARGET = "target"; - public static final String DELEGATE_FIELD_DELEGATE = "delegate"; + public static final String DELEGATE_FIELD_DELEGATE = "include"; private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; diff --git a/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java b/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java index ca9e62d..947087a 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/WebAsset.java @@ -39,6 +39,7 @@ import java.util.Locale; /* package private */ final class WebAsset extends AbstractAsset { private static final String MISSING_FIELD_FORMAT_STRING = "Expected %s to be set."; + private static final String SCHEME_HTTP = "http"; private final URL mUrl; @@ -105,6 +106,12 @@ import java.util.Locale; return toJson().hashCode(); } + @Override + public boolean followInsecureInclude() { + // Only allow insecure include file if the asset scheme is http. + return SCHEME_HTTP.equals(getScheme()); + } + /** * Checks that the input is a valid web asset. * diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 9d6d937..e47c7a0 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -184,16 +184,17 @@ <activity android:name=".tuner.TunerActivity" android:enabled="false" - android:icon="@*android:drawable/stat_sys_adb" + android:icon="@drawable/tuner" android:theme="@android:style/Theme.Material.Settings" android:label="@string/system_ui_tuner" + android:process=":tuner" android:exported="true"> <intent-filter> <action android:name="com.android.settings.action.EXTRA_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="com.android.settings.category" - android:value="com.android.settings.category.device" /> + android:value="com.android.settings.category.system" /> </activity> <!-- Alternate Recents --> @@ -319,6 +320,19 @@ <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <activity android:name=".egg.ShruggyActivity" + android:theme="@android:style/Theme.NoDisplay" + android:exported="true" + android:launchMode="singleInstance" + android:screenOrientation="locked" + android:process=":sweetsweetdesserts" + android:excludeFromRecents="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.android.internal.category.PLATLOGO" /> </intent-filter> </activity> diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md index 18ae4cb..258c76b 100644 --- a/packages/SystemUI/docs/demo_mode.md +++ b/packages/SystemUI/docs/demo_mode.md @@ -38,6 +38,8 @@ Command | Subcommand | Argument | Description | | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide | | ```level``` | Sets mobile signal strength level (null or 0-4) | ```carriernetworkchange``` | | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide) + | ```sims``` | | Sets the number of sims (1-8) + | ```nosim``` | | ```show``` to show icon, any other value to hide ```bars``` | | | Control the visual style of the bars (opaque, translucent, etc) | ```mode``` | | Sets the bars visual style (opaque, translucent, semi-transparent) ```status``` | | | Control the system status icons diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml index dc1e633..7b8975a 100644 --- a/packages/SystemUI/res/drawable-nodpi/icon.xml +++ b/packages/SystemUI/res/drawable-nodpi/icon.xml @@ -14,47 +14,30 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48dp" - android:height="48dp" - android:viewportWidth="560.0" - android:viewportHeight="560.0"> + android:width="48.0dp" + android:height="48.0dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> <path - android:pathData="M280.000000,288.000000m-260.000000,0.000000a260.000000,260.000000 0.000000,1.000000 1.000000,520.000000 0.000000a260.000000,260.000000 0.000000,1.000000 1.000000,-520.000000 0.000000" - android:fillColor="#14000000"/> + android:pathData="M24.0,2.0C11.8,2.0 2.0,11.8 2.0,24.0c0.0,6.1 2.5,11.6 6.4,15.6L39.6,8.4C35.6,4.5 30.1,2.0 24.0,2.0z" + android:fillColor="#F57C00"/> <path - android:pathData="M280.000000,285.000000m-255.000000,0.000000a255.000000,255.000000 0.000000,1.000000 1.000000,510.000000 0.000000a255.000000,255.000000 0.000000,1.000000 1.000000,-510.000000 0.000000" - android:fillColor="#26000000"/> + android:pathData="M39.6,8.4L8.4,39.6c4.0,4.0 9.5,6.4 15.6,6.4c12.2,0.0 22.0,-9.8 22.0,-22.0C46.0,17.9 43.5,12.4 39.6,8.4z" + android:fillColor="#FF9800"/> <path - android:pathData="M280.000000,282.000000m-252.000000,0.000000a252.000000,252.000000 0.000000,1.000000 1.000000,504.000000 0.000000a252.000000,252.000000 0.000000,1.000000 1.000000,-504.000000 0.000000" - android:fillColor="#26000000"/> + android:pathData="M45.9,25.9L34.0,14.0L14.0,34.0l11.9,11.9C36.5,45.0 45.0,36.5 45.9,25.9z" + android:fillAlpha="0.33" + android:fillColor="#F57C00"/> <path - android:pathData="M280.000000,280.000000m-250.000000,0.000000a250.000000,250.000000 0.000000,1.000000 1.000000,500.000000 0.000000a250.000000,250.000000 0.000000,1.000000 1.000000,-500.000000 0.000000" - android:fillColor="#9C27B0"/> - <path - android:pathData="M265.786011,244.938004l0.000000,8.768000c6.527000,-6.384000 15.303000,-10.321000 25.063000,-10.321000c20.214001,0.000000 36.429001,16.500000 36.429001,36.714001c0.000000,20.072001 -16.215000,36.500000 -36.429001,36.500000c-9.759000,0.000000 -18.107000,-3.651000 -24.634001,-9.759000l0.000000,25.839001l-10.107000,0.000000l0.000000,-87.740997L265.786011,244.937988L265.786011,244.938004zM267.330994,266.490997c-0.420000,0.706000 -1.125000,1.821000 -1.125000,4.277000l0.000000,18.813000c0.000000,1.759000 0.420000,2.740000 0.982000,3.723000c4.634000,7.929000 13.197000,13.339000 22.882999,13.339000c14.671000,0.000000 26.742001,-11.999000 26.742001,-26.669001c0.000000,-14.536000 -12.071000,-26.607000 -26.742001,-26.607000C280.454987,253.365997 271.963989,258.625000 267.330994,266.490997z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M427.973999,244.938004l0.000000,8.768000c6.526000,-6.384000 15.304000,-10.321000 25.062000,-10.321000c20.215000,0.000000 36.429001,16.500000 36.429001,36.714001c0.000000,20.072001 -16.214001,36.500000 -36.429001,36.500000c-9.758000,0.000000 -18.106001,-3.651000 -24.634001,-9.759000l0.000000,25.839001l-10.107000,0.000000l0.000000,-87.740997L427.973999,244.937988L427.973999,244.938004zM429.518005,266.490997c-0.419000,0.706000 -1.125000,1.821000 -1.125000,4.277000l0.000000,18.813000c0.000000,1.759000 0.420000,2.740000 0.982000,3.723000c4.634000,7.929000 13.196000,13.339000 22.884001,13.339000c14.670000,0.000000 26.740999,-11.999000 26.740999,-26.669001c0.000000,-14.536000 -12.071000,-26.607000 -26.740999,-26.607000C442.643005,253.365997 434.152008,258.625000 429.518005,266.490997z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M181.330994,279.893005c0.000000,20.214001 -16.357000,36.715000 -36.438000,36.715000c-20.214001,0.000000 -36.643002,-16.500999 -36.643002,-36.715000c0.000000,-20.070999 16.419001,-36.500000 36.643002,-36.500000C164.973007,243.393005 181.330994,259.821014 181.330994,279.893005zM171.151993,280.036011c0.000000,-14.669000 -11.723000,-26.669001 -26.259001,-26.669001c-14.741000,0.000000 -26.250000,12.000000 -26.250000,26.669001c0.000000,14.536000 11.509000,26.607000 26.250000,26.607000C159.429001,306.634003 171.151993,294.562012 171.151993,280.036011z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M408.384003,279.893005c0.000000,20.214001 -16.357000,36.715000 -36.437000,36.715000c-20.215000,0.000000 -36.644001,-16.500999 -36.644001,-36.715000c0.000000,-20.070999 16.420000,-36.500000 36.644001,-36.500000C392.026001,243.393005 408.384003,259.821014 408.384003,279.893005zM398.204987,280.036011c0.000000,-14.669000 -11.723000,-26.669001 -26.257999,-26.669001c-14.742000,0.000000 -26.250999,12.000000 -26.250999,26.669001c0.000000,14.536000 11.509000,26.607000 26.250999,26.607000C386.481995,306.634003 398.204987,294.562012 398.204987,280.036011z" + android:pathData="M24.0,24.0c0.0,0.0 0.0,2.2 0.0,5.0s0.0,5.0 0.0,5.0l10.0,-10.0L34.0,14.0L24.0,24.0z" android:fillColor="#FFFFFF"/> <path - android:pathData="M234.481995,227.320999l9.973000,0.000000l0.000000,10.250000l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M234.481995,244.865997l9.973000,0.000000l0.000000,70.195999l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> + android:pathData="M24.0,24.0L14.0,14.0l0.0,10.0l10.0,10.0c0.0,0.0 0.0,-2.2 0.0,-5.0S24.0,24.0 24.0,24.0z" + android:fillColor="#EEEEEE"/> <path - android:pathData="M88.392998,227.320999l9.973000,0.000000l0.000000,87.740997l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> + android:pathData="M14.0,34.0l10.0,0.0 -10.0,-10.0z" + android:fillColor="#DDDDDD"/> <path - android:pathData="M191.231995,227.320999l9.973000,0.000000l0.000000,87.740997l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M212.856995,227.320999l9.974000,0.000000l0.000000,87.740997l-9.974000,0.000000z" - android:fillColor="#FFFFFF"/> + android:pathData="M34.0,34.0l0.0,-10.0 -10.0,10.0z" + android:fillColor="#DDDDDD"/> </vector> diff --git a/packages/SystemUI/res/drawable-nodpi/tuner.xml b/packages/SystemUI/res/drawable-nodpi/tuner.xml new file mode 100644 index 0000000..e27423f --- /dev/null +++ b/packages/SystemUI/res/drawable-nodpi/tuner.xml @@ -0,0 +1,27 @@ +<!-- + Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="48.0dp" + android:height="48.0dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> + <path + android:fillColor="#FF000000" + android:pathData="M29.9,24.8c0.0,-0.3 0.1,-0.5 0.1,-0.8s0.0,-0.5 -0.1,-0.8l1.7,-1.3c0.2,-0.1 0.2,-0.3 0.1,-0.5l-1.6,-2.8c-0.1,-0.2 -0.3,-0.2 -0.5,-0.2l-2.0,0.8c-0.4,-0.3 -0.9,-0.6 -1.4,-0.8L26.0,16.3c0.0,-0.2 -0.2,-0.3 -0.4,-0.3l-3.2,0.0c-0.2,0.0 -0.4,0.1 -0.4,0.3l-0.3,2.1c-0.5,0.2 -0.9,0.5 -1.4,0.8l-2.0,-0.8c-0.2,-0.1 -0.4,0.0 -0.5,0.2l-1.6,2.8c-0.1,0.2 -0.1,0.4 0.1,0.5l1.7,1.3c0.0,0.3 -0.1,0.5 -0.1,0.8s0.0,0.5 0.1,0.8l-1.7,1.3c-0.2,0.1 -0.2,0.3 -0.1,0.5l1.6,2.8c0.1,0.2 0.3,0.2 0.5,0.2l2.0,-0.8c0.4,0.3 0.9,0.6 1.4,0.8l0.3,2.1c0.0,0.2 0.2,0.3 0.4,0.3l3.2,0.0c0.2,0.0 0.4,-0.1 0.4,-0.3l0.3,-2.1c0.5,-0.2 0.9,-0.5 1.4,-0.8l2.0,0.8c0.2,0.1 0.4,0.0 0.5,-0.2l1.6,-2.8c0.1,-0.2 0.1,-0.4 -0.1,-0.5L29.9,24.8zM24.0,26.8c-1.5,0.0 -2.8,-1.3 -2.8,-2.8s1.3,-2.8 2.8,-2.8s2.8,1.3 2.8,2.8S25.5,26.8 24.0,26.8z"/> + <path + android:fillColor="#FF000000" + android:pathData="M18.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S18.6,38.0 18.0,38.0zM24.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S24.6,38.0 24.0,38.0zM30.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S30.6,38.0 30.0,38.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,28.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM42.0,34.0L6.0,34.0L6.0,14.0l36.0,0.0L42.0,34.0zM9.0,12.0L7.0,12.0l0.0,-2.0l2.0,0.0L9.0,12.0zM13.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,12.0zM17.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L17.0,12.0z"/> +</vector> diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml index 2160ca3..731d4c1 100644 --- a/packages/SystemUI/res/layout/zen_mode_panel.xml +++ b/packages/SystemUI/res/layout/zen_mode_panel.xml @@ -61,6 +61,7 @@ android:layout_height="wrap_content" android:layout_marginTop="12dp" android:layout_marginStart="24dp" + android:textDirection="locale" android:lineSpacingMultiplier="1.20029" android:layout_toStartOf="@id/zen_introduction_confirm" android:textAppearance="@style/TextAppearance.QS.Introduction" /> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index aac0311..f1bbb0d 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1023,7 +1023,7 @@ <string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string> <!-- Name of special SystemUI debug settings --> - <string name="system_ui_tuner">SystemUI Tuner</string> + <string name="system_ui_tuner">System UI tuner</string> <!-- Name of quick settings --> <string name="quick_settings">Quick Settings</string> @@ -1033,4 +1033,9 @@ <!-- Name of a quick settings tile controlled by broadcast --> <string name="broadcast_tile">Broadcast Tile</string> + + <!-- For preview release. DO NOT TRANSLATE --> + <string name="regrettable_lack_of_easter_egg"> + ¯\\_(ツ)_/¯ + </string> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java b/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java new file mode 100644 index 0000000..7459957 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.egg; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.widget.Toast; +import com.android.systemui.R; + +public class ShruggyActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Toast.makeText(this, getString(R.string.regrettable_lack_of_easter_egg), + Toast.LENGTH_SHORT).show(); + Log.v("SystemUI", "Hey, it's just a preview; what did you expect?"); + finish(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java index 111484b..a318efc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java @@ -42,14 +42,21 @@ public class QSDetailClipper { } final int w = mDetail.getWidth() - x; final int h = mDetail.getHeight() - y; + int innerR = 0; + if (x < 0 || w < 0 || y < 0 || h < 0) { + innerR = Math.abs(x); + innerR = Math.min(innerR, Math.abs(y)); + innerR = Math.min(innerR, Math.abs(w)); + innerR = Math.min(innerR, Math.abs(h)); + } int r = (int) Math.ceil(Math.sqrt(x * x + y * y)); r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + y * y))); r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + h * h))); r = (int) Math.max(r, Math.ceil(Math.sqrt(x * x + h * h))); if (in) { - mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, 0, r); + mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, innerR, r); } else { - mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, r, 0); + mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, r, innerR); } mAnimator.setDuration((long)(mAnimator.getDuration() * 1.5)); if (listener != null) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index b4ae20d..cd4f299 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -215,9 +215,19 @@ public class QSPanel extends ViewGroup { mFooter.refreshState(); } - public void showDetailAdapter(boolean show, DetailAdapter adapter) { + public void showDetailAdapter(boolean show, DetailAdapter adapter, int[] locationInWindow) { + int xInWindow = locationInWindow[0]; + int yInWindow = locationInWindow[1]; + mDetail.getLocationInWindow(locationInWindow); + Record r = new Record(); r.detailAdapter = adapter; + r.x = xInWindow - locationInWindow[0]; + r.y = yInWindow - locationInWindow[1]; + + locationInWindow[0] = xInWindow; + locationInWindow[1] = yInWindow; + showDetail(show, r); } @@ -337,7 +347,13 @@ public class QSPanel extends ViewGroup { if (r instanceof TileRecord) { handleShowDetailTile((TileRecord) r, show); } else { - handleShowDetailImpl(r, show, getWidth() /* x */, 0/* y */); + int x = 0; + int y = 0; + if (r != null) { + x = r.x; + y = r.y; + } + handleShowDetailImpl(r, show, x, y); } } @@ -558,6 +574,8 @@ public class QSPanel extends ViewGroup { private static class Record { View detailView; DetailAdapter detailAdapter; + int x; + int y; } protected static final class TileRecord extends Record { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java index 3b217df..72bb136 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java @@ -24,23 +24,21 @@ import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; -import com.android.internal.logging.MetricsLogger; import com.android.systemui.qs.QSTile.State; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.FlashlightController; +import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.Listenable; import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.RotationLockController; -import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.ZenModeController; import java.util.Collection; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 1721335..dcf0438 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -30,9 +30,11 @@ import com.android.systemui.qs.QSTile; import com.android.systemui.qs.QSTileView; import com.android.systemui.qs.SignalTileView; import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.MobileDataController; import com.android.systemui.statusbar.policy.NetworkController.MobileDataController.DataUsageInfo; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; +import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.SignalCallbackAdapter; /** Quick settings tile: Cellular **/ public class CellularTile extends QSTile<QSTile.SignalState> { @@ -63,9 +65,9 @@ public class CellularTile extends QSTile<QSTile.SignalState> { @Override public void setListening(boolean listening) { if (listening) { - mController.addNetworkSignalChangedCallback(mCallback); + mController.addSignalCallback(mSignalCallback); } else { - mController.removeNetworkSignalChangedCallback(mCallback); + mController.removeSignalCallback(mSignalCallback); } } @@ -138,7 +140,6 @@ public class CellularTile extends QSTile<QSTile.SignalState> { private static final class CallbackInfo { boolean enabled; boolean wifiEnabled; - boolean wifiConnected; boolean airplaneModeEnabled; int mobileSignalIconId; String signalContentDescription; @@ -151,40 +152,39 @@ public class CellularTile extends QSTile<QSTile.SignalState> { boolean isDataTypeIconWide; } - private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { + private final SignalCallback mSignalCallback = new SignalCallbackAdapter() { private final CallbackInfo mInfo = new CallbackInfo(); - @Override - public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, - boolean activityIn, boolean activityOut, - String wifiSignalContentDescriptionId, String description) { + public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description) { mInfo.wifiEnabled = enabled; - mInfo.wifiConnected = connected; refreshState(mInfo); } @Override - public void onMobileDataSignalChanged(boolean enabled, - int mobileSignalIconId, - String mobileSignalContentDescriptionId, int dataTypeIconId, - boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description, - boolean isDataTypeIconWide) { - mInfo.enabled = enabled; - mInfo.mobileSignalIconId = mobileSignalIconId; - mInfo.signalContentDescription = mobileSignalContentDescriptionId; - mInfo.dataTypeIconId = dataTypeIconId; - mInfo.dataContentDescription = dataTypeContentDescriptionId; + public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, + int darkStatusIcon, int statusType, int qsType, boolean activityIn, + boolean activityOut, String typeContentDescription, String description, + boolean isWide, int subId) { + if (qsIcon == null) { + // Not data sim, don't display. + return; + } + mInfo.enabled = qsIcon.visible; + mInfo.mobileSignalIconId = qsIcon.icon; + mInfo.signalContentDescription = qsIcon.contentDescription; + mInfo.dataTypeIconId = qsType; + mInfo.dataContentDescription = typeContentDescription; mInfo.activityIn = activityIn; mInfo.activityOut = activityOut; mInfo.enabledDesc = description; - mInfo.isDataTypeIconWide = isDataTypeIconWide; + mInfo.isDataTypeIconWide = qsType != 0 && isWide; refreshState(mInfo); } @Override - public void onNoSimVisibleChanged(boolean visible) { - mInfo.noSim = visible; + public void setNoSims(boolean show) { + mInfo.noSim = show; if (mInfo.noSim) { // Make sure signal gets cleared out when no sims. mInfo.mobileSignalIconId = 0; @@ -199,12 +199,13 @@ public class CellularTile extends QSTile<QSTile.SignalState> { } @Override - public void onAirplaneModeChanged(boolean enabled) { - mInfo.airplaneModeEnabled = enabled; + public void setIsAirplaneMode(IconState icon) { + mInfo.airplaneModeEnabled = icon.visible; refreshState(mInfo); } - public void onMobileDataEnabled(boolean enabled) { + @Override + public void setMobileDataEnabled(boolean enabled) { mDetailAdapter.setMobileDataEnabled(enabled); } }; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index c3f9e33..9504ea3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -16,8 +16,6 @@ package com.android.systemui.qs.tiles; -import java.util.List; - import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -36,7 +34,11 @@ import com.android.systemui.qs.QSTileView; import com.android.systemui.qs.SignalTileView; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; +import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.SignalCallbackAdapter; + +import java.util.List; /** Quick settings tile: Wifi **/ public class WifiTile extends QSTile<QSTile.SignalState> { @@ -67,9 +69,9 @@ public class WifiTile extends QSTile<QSTile.SignalState> { @Override public void setListening(boolean listening) { if (listening) { - mController.addNetworkSignalChangedCallback(mCallback); + mController.addSignalCallback(mSignalCallback); } else { - mController.removeNetworkSignalChangedCallback(mCallback); + mController.removeSignalCallback(mSignalCallback); } } @@ -211,46 +213,21 @@ public class WifiTile extends QSTile<QSTile.SignalState> { } } - private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { + private final SignalCallback mSignalCallback = new SignalCallbackAdapter() { @Override - public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, - boolean activityIn, boolean activityOut, - String wifiSignalContentDescriptionId, String description) { + public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description) { if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled); final CallbackInfo info = new CallbackInfo(); info.enabled = enabled; - info.connected = connected; - info.wifiSignalIconId = wifiSignalIconId; + info.connected = qsIcon.visible; + info.wifiSignalIconId = qsIcon.icon; info.enabledDesc = description; info.activityIn = activityIn; info.activityOut = activityOut; - info.wifiSignalContentDescription = wifiSignalContentDescriptionId; + info.wifiSignalContentDescription = qsIcon.contentDescription; refreshState(info); } - - @Override - public void onMobileDataSignalChanged(boolean enabled, - int mobileSignalIconId, - String mobileSignalContentDescriptionId, int dataTypeIconId, - boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description, - boolean isDataTypeIconWide) { - // noop - } - - public void onNoSimVisibleChanged(boolean noSims) { - // noop - } - - @Override - public void onAirplaneModeChanged(boolean enabled) { - // noop - } - - @Override - public void onMobileDataEnabled(boolean enabled) { - // noop - } }; private final class WifiDetailAdapter implements DetailAdapter, diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 2d1fab0..c702673 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -621,10 +621,11 @@ public class Recents extends SystemUI mHeaderBar.draw(c); c.setBitmap(null); } + Bitmap thumbnailImmutable = thumbnail.createAshmemBitmap(); mStartAnimationTriggered = false; return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, - thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(), + thumbnailImmutable, toTaskRect.left, toTaskRect.top, toTaskRect.width(), toTaskRect.height(), mHandler, this); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index 1377975..b3e6221 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -490,6 +490,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV // Notify the system to skip the thumbnail layer by using an ALPHA_8 bitmap b = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); } + Bitmap bImmut = b.createAshmemBitmap(); ActivityOptions.OnAnimationStartedListener animStartedListener = null; if (lockToTask) { animStartedListener = new ActivityOptions.OnAnimationStartedListener() { @@ -515,7 +516,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV sourceView.getHandler(), animStartedListener); } else { opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView, - b, offsetX, offsetY, transform.rect.width(), transform.rect.height(), + bImmut, offsetX, offsetY, transform.rect.width(), transform.rect.height(), sourceView.getHandler(), animStartedListener); } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 715f4e4..be33085 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -194,7 +194,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi // we compose the final post-save notification below. mNotificationBuilder.setLargeIcon(croppedIcon); // But we still don't set it for the expanded view, allowing the smallIcon to show here. - mNotificationStyle.bigLargeIcon(null); + mNotificationStyle.bigLargeIcon((Bitmap) null); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 2913c7d..1e488f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1390,9 +1390,9 @@ public abstract class BaseStatusBar extends SystemUI implements final ImageView profileBadge = (ImageView) publicViewLocal.findViewById( R.id.profile_badge_line3); - final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( entry.notification.getUser(), - entry.notification.getNotification().icon, + entry.notification.getNotification().getSmallIcon(), entry.notification.getNotification().iconLevel, entry.notification.getNotification().number, entry.notification.getNotification().tickerText); @@ -1770,9 +1770,9 @@ public abstract class BaseStatusBar extends SystemUI implements sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n); iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( sbn.getUser(), - n.icon, + n.getSmallIcon(), n.iconLevel, n.number, n.tickerText); @@ -1916,9 +1916,9 @@ public abstract class BaseStatusBar extends SystemUI implements try { if (entry.icon != null) { // Update the icon - final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( notification.getUser(), - n.icon, + n.getSmallIcon(), n.iconLevel, n.number, n.tickerText); @@ -1938,9 +1938,9 @@ public abstract class BaseStatusBar extends SystemUI implements } if (!updateSuccessful) { if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key); - final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( notification.getUser(), - n.icon, + n.getSmallIcon(), n.iconLevel, n.number, n.tickerText); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java index 9e2207e..2dc521e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java @@ -105,6 +105,13 @@ public class DelegateViewHelper { return mPanelShowing; } + public void abortCurrentGesture() { + if (mStarted) { + mStarted = false; + mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, false); + } + } + public void setSourceView(View view) { mSourceView = view; if (mSourceView != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index 17e2cb5..3feec9e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -59,6 +59,12 @@ public abstract class ExpandableView extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int ownMaxHeight = mMaxViewHeight; + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY; + if (hasFixedHeight) { + // We have a height set in our layout, so we want to be at most as big as given + ownMaxHeight = Math.min(MeasureSpec.getSize(heightMeasureSpec), ownMaxHeight); + } int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST); int maxChildHeight = 0; int childCount = getChildCount(); @@ -85,7 +91,7 @@ public abstract class ExpandableView extends FrameLayout { mMatchParentViews.add(child); } } - int ownHeight = Math.min(ownMaxHeight, maxChildHeight); + int ownHeight = hasFixedHeight ? ownMaxHeight : Math.min(ownMaxHeight, maxChildHeight); newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY); for (View child : mMatchParentViews) { child.measure(getChildMeasureSpec( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index f6629dd..14e491b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -33,6 +33,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import com.android.systemui.R; +import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkControllerImpl; import com.android.systemui.statusbar.policy.SecurityController; @@ -42,7 +43,7 @@ import java.util.List; // Intimately tied to the design of res/layout/signal_cluster_view.xml public class SignalClusterView extends LinearLayout - implements NetworkControllerImpl.SignalCluster, + implements NetworkControllerImpl.SignalCallback, SecurityController.SecurityControllerCallback { static final String TAG = "SignalClusterView"; @@ -59,7 +60,7 @@ public class SignalClusterView private int mWifiStrengthId = 0; private boolean mIsAirplaneMode = false; private int mAirplaneIconId = 0; - private int mAirplaneContentDescription; + private String mAirplaneContentDescription; private String mWifiDescription; private String mEthernetDescription; private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>(); @@ -166,35 +167,36 @@ public class SignalClusterView } @Override - public void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription) { - mWifiVisible = visible; - mWifiStrengthId = strengthIcon; - mWifiDescription = contentDescription; + public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description) { + mWifiVisible = statusIcon.visible; + mWifiStrengthId = statusIcon.icon; + mWifiDescription = statusIcon.contentDescription; apply(); } @Override - public void setMobileDataIndicators(boolean visible, int strengthIcon, int darkStrengthIcon, - int typeIcon, String contentDescription, String typeContentDescription, - boolean isTypeIconWide, int subId) { + public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int darkStatusIcon, + int statusType, int qsType, boolean activityIn, boolean activityOut, + String typeContentDescription, String description, boolean isWide, int subId) { PhoneState state = getOrInflateState(subId); - state.mMobileVisible = visible; - state.mMobileStrengthId = strengthIcon; - state.mMobileDarkStrengthId = darkStrengthIcon; - state.mMobileTypeId = typeIcon; - state.mMobileDescription = contentDescription; + state.mMobileVisible = statusIcon.visible; + state.mMobileStrengthId = statusIcon.icon; + state.mMobileDarkStrengthId = darkStatusIcon; + state.mMobileTypeId = statusType; + state.mMobileDescription = statusIcon.contentDescription; state.mMobileTypeDescription = typeContentDescription; - state.mIsMobileTypeIconWide = isTypeIconWide; + state.mIsMobileTypeIconWide = statusType != 0 && isWide; apply(); } @Override - public void setEthernetIndicators(boolean visible, int icon, String contentDescription) { - mEthernetVisible = visible; - mEthernetIconId = icon; - mEthernetDescription = contentDescription; + public void setEthernetIndicators(IconState state) { + mEthernetVisible = state.visible; + mEthernetIconId = state.icon; + mEthernetDescription = state.contentDescription; apply(); } @@ -239,15 +241,20 @@ public class SignalClusterView } @Override - public void setIsAirplaneMode(boolean is, int airplaneIconId, int contentDescription) { - mIsAirplaneMode = is; - mAirplaneIconId = airplaneIconId; - mAirplaneContentDescription = contentDescription; + public void setIsAirplaneMode(IconState icon) { + mIsAirplaneMode = icon.visible; + mAirplaneIconId = icon.icon; + mAirplaneContentDescription = icon.contentDescription; apply(); } @Override + public void setMobileDataEnabled(boolean enabled) { + // Don't care. + } + + @Override public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) { // Standard group layout onPopulateAccessibilityEvent() implementations // ignore content description, so populate manually @@ -343,8 +350,7 @@ public class SignalClusterView if (mIsAirplaneMode) { mAirplane.setImageResource(mAirplaneIconId); - mAirplane.setContentDescription(mAirplaneContentDescription != 0 ? - mContext.getString(mAirplaneContentDescription) : null); + mAirplane.setContentDescription(mAirplaneContentDescription); mAirplane.setVisibility(View.VISIBLE); } else { mAirplane.setVisibility(View.GONE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index e6847d8..3294e15 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -24,6 +24,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.os.UserHandle; import android.text.TextUtils; import android.util.AttributeSet; @@ -100,13 +101,23 @@ public class StatusBarIconView extends AnimatedImageView { return a.equals(b); } + public boolean equalIcons(Icon a, Icon b) { + if (a == b) return true; + if (a.getType() != b.getType()) return false; + switch (a.getType()) { + case Icon.TYPE_RESOURCE: + return a.getResPackage().equals(b.getResPackage()) && a.getResId() == b.getResId(); + case Icon.TYPE_URI: + return a.getUriString().equals(b.getUriString()); + default: + return false; + } + } /** * Returns whether the set succeeded. */ public boolean set(StatusBarIcon icon) { - final boolean iconEquals = mIcon != null - && streq(mIcon.iconPackage, icon.iconPackage) - && mIcon.iconId == icon.iconId; + final boolean iconEquals = mIcon != null && equalIcons(mIcon.icon, icon.icon); final boolean levelEquals = iconEquals && mIcon.iconLevel == icon.iconLevel; final boolean visibilityEquals = mIcon != null @@ -167,45 +178,18 @@ public class StatusBarIconView extends AnimatedImageView { } /** - * Returns the right icon to use for this item, respecting the iconId and - * iconPackage (if set) + * Returns the right icon to use for this item * - * @param context Context to use to get resources if iconPackage is not set + * @param context Context to use to get resources * @return Drawable for this item, or null if the package or item could not * be found */ public static Drawable getIcon(Context context, StatusBarIcon icon) { - Resources r = null; - - if (icon.iconPackage != null) { - try { - int userId = icon.user.getIdentifier(); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_OWNER; - } - r = context.getPackageManager() - .getResourcesForApplicationAsUser(icon.iconPackage, userId); - } catch (PackageManager.NameNotFoundException ex) { - Log.e(TAG, "Icon package not found: " + icon.iconPackage); - return null; - } - } else { - r = context.getResources(); + int userId = icon.user.getIdentifier(); + if (userId == UserHandle.USER_ALL) { + userId = UserHandle.USER_OWNER; } - - if (icon.iconId == 0) { - return null; - } - - try { - return r.getDrawable(icon.iconId); - } catch (RuntimeException e) { - Log.w(TAG, "Icon not found in " - + (icon.iconPackage != null ? icon.iconId : "<system>") - + ": " + Integer.toHexString(icon.iconId)); - } - - return null; + return icon.icon.loadDrawableAsUser(context, userId); } public StatusBarIcon getStatusBarIcon() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 44168bc..26d1c86 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.UserHandle; import android.view.Gravity; @@ -132,8 +133,7 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { break; } else { StatusBarIcon icon = v.getStatusBarIcon(); - icon.iconPackage = iconPkg; - icon.iconId = iconId; + icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId); v.set(icon); v.updateDrawable(); return; @@ -152,4 +152,4 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { v.set(icon); addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize)); } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java index 82f5a9e..f11d83c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java @@ -42,6 +42,8 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener private boolean mKeyguardMode; final UserManager mUserManager; + private final int[] mTmpInt2 = new int[2]; + public MultiUserSwitch(Context context, AttributeSet attrs) { super(context, attrs); mUserManager = UserManager.get(getContext()); @@ -77,7 +79,15 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener UserSwitcherController userSwitcherController = mQsPanel.getHost().getUserSwitcherController(); if (userSwitcherController != null) { - mQsPanel.showDetailAdapter(true, userSwitcherController.userDetailAdapter); + View center = getChildCount() > 0 ? getChildAt(0) : this; + + center.getLocationInWindow(mTmpInt2); + mTmpInt2[0] += center.getWidth() / 2; + mTmpInt2[1] += center.getHeight() / 2; + + mQsPanel.showDetailAdapter(true, + userSwitcherController.userDetailAdapter, + mTmpInt2); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 7077a17..1dec227 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -245,6 +245,11 @@ public class NavigationBarView extends LinearLayout { return intercept; } + public void abortCurrentGesture() { + mDelegateHelper.abortCurrentGesture(); + getHomeButton().abortCurrentGesture(); + } + private H mHandler = new H(); public View getCurrentView() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 9ef9211..c10be7c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -117,6 +117,7 @@ public class NotificationPanelView extends PanelView implements * intercepted yet. */ private boolean mIntercepting; + private boolean mPanelExpanded; private boolean mQsExpanded; private boolean mQsExpandedWhenExpandingStarted; private boolean mQsFullyExpanded; @@ -1496,13 +1497,22 @@ public class NotificationPanelView extends PanelView implements updateHeader(); updateUnlockIcon(); updateNotificationTranslucency(); - mHeadsUpManager.setIsExpanded(!isFullyCollapsed()); + updatePanelExpanded(); mNotificationStackScroller.setShadeExpanded(!isFullyCollapsed()); if (DEBUG) { invalidate(); } } + private void updatePanelExpanded() { + boolean isExpanded = !isFullyCollapsed(); + if (mPanelExpanded != isExpanded) { + mHeadsUpManager.setIsExpanded(isExpanded); + mStatusBar.setPanelExpanded(isExpanded); + mPanelExpanded = isExpanded; + } + } + /** * @return a temporary override of {@link #mQsMaxExpansionHeight}, which is needed when * collapsing QS / the panel when QS was scrolled diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java index 1186a33..9e5cefd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java @@ -99,7 +99,7 @@ public class ObservableScrollView extends ScrollView { } else if (!mTouchEnabled) { MotionEvent cancel = MotionEvent.obtain(ev); cancel.setAction(MotionEvent.ACTION_CANCEL); - super.dispatchTouchEvent(ev); + super.dispatchTouchEvent(cancel); cancel.recycle(); mTouchCancelled = true; return false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 887b8f4..9fe591e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -779,9 +779,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster); final SignalClusterView signalClusterQs = (SignalClusterView) mHeader.findViewById(R.id.signal_cluster); - mNetworkController.addSignalCluster(signalCluster); - mNetworkController.addSignalCluster(signalClusterKeyguard); - mNetworkController.addSignalCluster(signalClusterQs); + mNetworkController.addSignalCallback(signalCluster); + mNetworkController.addSignalCallback(signalClusterKeyguard); + mNetworkController.addSignalCallback(signalClusterQs); signalCluster.setSecurityController(mSecurityController); signalCluster.setNetworkController(mNetworkController); signalClusterKeyguard.setSecurityController(mSecurityController); @@ -1013,7 +1013,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, invokeAssistGesture(true /* vibrate */); awakenDreams(); if (mNavigationBarView != null) { - mNavigationBarView.getHomeButton().abortCurrentGesture(); + mNavigationBarView.abortCurrentGesture(); } } }; @@ -1967,6 +1967,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return !mUnlockMethodCache.isCurrentlyInsecure(); } + public void setPanelExpanded(boolean isExpanded) { + mStatusBarWindowManager.setPanelExpanded(isExpanded); + } + /** * All changes to the status bar and notifications funnel through here and are batched. */ @@ -2027,7 +2031,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Expand the window to encompass the full screen in anticipation of the drag. // This is only possible to do atomically because the status bar is at the top of the screen! - mStatusBarWindowManager.setStatusBarExpanded(true); + mStatusBarWindowManager.setPanelVisible(true); mStatusBarView.setFocusable(false); visibilityChanged(true); @@ -2156,7 +2160,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, visibilityChanged(false); // Shrink the window to the size of the status bar only - mStatusBarWindowManager.setStatusBarExpanded(false); + mStatusBarWindowManager.setPanelVisible(false); mStatusBarWindowManager.setForceStatusBarVisible(false); mStatusBarView.setFocusable(true); @@ -3087,6 +3091,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } mContext.unregisterReceiver(mBroadcastReceiver); mAssistManager.destroy(); + + final SignalClusterView signalCluster = + (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster); + final SignalClusterView signalClusterKeyguard = + (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster); + final SignalClusterView signalClusterQs = + (SignalClusterView) mHeader.findViewById(R.id.signal_cluster); + mNetworkController.addSignalCallback(signalCluster); + mNetworkController.addSignalCallback(signalClusterKeyguard); + mNetworkController.addSignalCallback(signalClusterQs); } private boolean mDemoModeAllowed; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index 422d868..4f1c652 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -114,12 +114,12 @@ public class StatusBarWindowManager { } private void applyFocusableFlag(State state) { + boolean panelFocusable = state.statusBarFocusable && state.panelExpanded; if (state.isKeyguardShowingAndNotOccluded() && state.keyguardNeedsInput - && state.bouncerShowing - || BaseStatusBar.ENABLE_REMOTE_INPUT && state.statusBarExpanded) { + && state.bouncerShowing || BaseStatusBar.ENABLE_REMOTE_INPUT && panelFocusable) { mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - } else if (state.isKeyguardShowingAndNotOccluded() || state.statusBarFocusable) { + } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) { mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mLpChanged.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; } else { @@ -130,7 +130,7 @@ public class StatusBarWindowManager { private void applyHeight(State state) { boolean expanded = !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded() - || state.statusBarExpanded || state.keyguardFadingAway || state.bouncerShowing + || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing || state.headsUpShowing); if (expanded) { mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT; @@ -213,9 +213,9 @@ public class StatusBarWindowManager { apply(mCurrentState); } - public void setStatusBarExpanded(boolean expanded) { - mCurrentState.statusBarExpanded = expanded; - mCurrentState.statusBarFocusable = expanded; + public void setPanelVisible(boolean visible) { + mCurrentState.panelVisible = visible; + mCurrentState.statusBarFocusable = visible; apply(mCurrentState); } @@ -267,11 +267,17 @@ public class StatusBarWindowManager { apply(mCurrentState); } + public void setPanelExpanded(boolean isExpanded) { + mCurrentState.panelExpanded = isExpanded; + apply(mCurrentState); + } + private static class State { boolean keyguardShowing; boolean keyguardOccluded; boolean keyguardNeedsInput; - boolean statusBarExpanded; + boolean panelVisible; + boolean panelExpanded; boolean statusBarFocusable; boolean bouncerShowing; boolean keyguardFadingAway; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java index 5893cb2..0eb7197 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java @@ -45,7 +45,7 @@ public class AccessPointControllerImpl private static final String EXTRA_START_CONNECT_SSID = "wifi_start_connect_ssid"; private static final int[] ICONS = { - R.drawable.ic_qs_wifi_0, + R.drawable.ic_qs_wifi_full_0, R.drawable.ic_qs_wifi_full_1, R.drawable.ic_qs_wifi_full_2, R.drawable.ic_qs_wifi_full_3, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java index 8d4f302..ed98a15 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -18,7 +18,9 @@ package com.android.systemui.statusbar.policy; import android.bluetooth.BluetoothAdapter; import android.content.Context; +import android.os.Handler; import android.os.Looper; +import android.os.Message; import android.util.Log; import com.android.settingslib.bluetooth.BluetoothCallback; @@ -42,9 +44,12 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa private boolean mConnecting; private CachedBluetoothDevice mLastDevice; + private final H mHandler = new H(); + public BluetoothControllerImpl(Context context, Looper bgLooper) { mLocalBluetoothManager = LocalBluetoothManager.getInstance(context, null); if (mLocalBluetoothManager != null) { + mLocalBluetoothManager.getEventManager().setReceiverHandler(new Handler(bgLooper)); mLocalBluetoothManager.getEventManager().registerCallback(this); onBluetoothStateChanged( mLocalBluetoothManager.getBluetoothAdapter().getBluetoothState()); @@ -54,6 +59,9 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("BluetoothController state:"); pw.print(" mLocalBluetoothManager="); pw.println(mLocalBluetoothManager); + if (mLocalBluetoothManager == null) { + return; + } pw.print(" mEnabled="); pw.println(mEnabled); pw.print(" mConnecting="); pw.println(mConnecting); pw.print(" mLastDevice="); pw.println(mLastDevice); @@ -71,7 +79,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa public void addStateChangedCallback(Callback cb) { mCallbacks.add(cb); - fireStateChange(cb); + mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED); } @Override @@ -132,22 +140,6 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa : null; } - private void firePairedDevicesChanged() { - for (Callback cb : mCallbacks) { - cb.onBluetoothDevicesChanged(); - } - } - - private void fireStateChange() { - for (Callback cb : mCallbacks) { - fireStateChange(cb); - } - } - - private void fireStateChange(Callback cb) { - cb.onBluetoothStateChange(mEnabled, mConnecting); - } - private void updateConnected() { if (mLastDevice != null && mLastDevice.isConnected()) { // Our current device is still valid. @@ -163,7 +155,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa @Override public void onBluetoothStateChanged(int bluetoothState) { mEnabled = bluetoothState == BluetoothAdapter.STATE_ON; - fireStateChange(); + mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED); } @Override @@ -175,25 +167,25 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { cachedDevice.registerCallback(this); updateConnected(); - firePairedDevicesChanged(); + mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED); } @Override public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { updateConnected(); - firePairedDevicesChanged(); + mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED); } @Override public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) { updateConnected(); - firePairedDevicesChanged(); + mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED); } @Override public void onDeviceAttributesChanged() { updateConnected(); - firePairedDevicesChanged(); + mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED); } @Override @@ -201,6 +193,39 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa mConnecting = state == BluetoothAdapter.STATE_CONNECTING; mLastDevice = cachedDevice; updateConnected(); - fireStateChange(); + mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED); + } + + private final class H extends Handler { + private static final int MSG_PAIRED_DEVICES_CHANGED = 1; + private static final int MSG_STATE_CHANGED = 2; + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_PAIRED_DEVICES_CHANGED: + firePairedDevicesChanged(); + break; + case MSG_STATE_CHANGED: + fireStateChange(); + break; + } + } + + private void firePairedDevicesChanged() { + for (BluetoothController.Callback cb : mCallbacks) { + cb.onBluetoothDevicesChanged(); + } + } + + private void fireStateChange() { + for (BluetoothController.Callback cb : mCallbacks) { + fireStateChange(cb); + } + } + + private void fireStateChange(BluetoothController.Callback cb) { + cb.onBluetoothStateChange(mEnabled, mConnecting); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java new file mode 100644 index 0000000..7f52191 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.policy; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.telephony.SubscriptionInfo; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Implements network listeners and forwards the calls along onto other listeners but on + * the current or specified Looper. + */ +public class CallbackHandler extends Handler implements EmergencyListener, SignalCallback { + private static final int MSG_EMERGENCE_CHANGED = 0; + private static final int MSG_SUBS_CHANGED = 1; + private static final int MSG_NO_SIM_VISIBLE_CHANGED = 2; + private static final int MSG_ETHERNET_CHANGED = 3; + private static final int MSG_AIRPLANE_MODE_CHANGED = 4; + private static final int MSG_MOBILE_DATA_ENABLED_CHANGED = 5; + private static final int MSG_ADD_REMOVE_EMERGENCY = 6; + private static final int MSG_ADD_REMOVE_SIGNAL = 7; + + // All the callbacks. + private final ArrayList<EmergencyListener> mEmergencyListeners = new ArrayList<>(); + private final ArrayList<SignalCallback> mSignalCallbacks = new ArrayList<>(); + + public CallbackHandler() { + super(); + } + + @VisibleForTesting + CallbackHandler(Looper looper) { + super(looper); + } + + @Override + @SuppressWarnings("unchecked") + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_EMERGENCE_CHANGED: + for (EmergencyListener listener : mEmergencyListeners) { + listener.setEmergencyCallsOnly(msg.arg1 != 0); + } + break; + case MSG_SUBS_CHANGED: + for (SignalCallback signalCluster : mSignalCallbacks) { + signalCluster.setSubs((List<SubscriptionInfo>) msg.obj); + } + break; + case MSG_NO_SIM_VISIBLE_CHANGED: + for (SignalCallback signalCluster : mSignalCallbacks) { + signalCluster.setNoSims(msg.arg1 != 0); + } + break; + case MSG_ETHERNET_CHANGED: + for (SignalCallback signalCluster : mSignalCallbacks) { + signalCluster.setEthernetIndicators((IconState) msg.obj); + } + break; + case MSG_AIRPLANE_MODE_CHANGED: + for (SignalCallback signalCluster : mSignalCallbacks) { + signalCluster.setIsAirplaneMode((IconState) msg.obj); + } + break; + case MSG_MOBILE_DATA_ENABLED_CHANGED: + for (SignalCallback signalCluster : mSignalCallbacks) { + signalCluster.setMobileDataEnabled(msg.arg1 != 0); + } + break; + case MSG_ADD_REMOVE_EMERGENCY: + if (msg.arg1 != 0) { + mEmergencyListeners.add((EmergencyListener) msg.obj); + } else { + mEmergencyListeners.remove((EmergencyListener) msg.obj); + } + break; + case MSG_ADD_REMOVE_SIGNAL: + if (msg.arg1 != 0) { + mSignalCallbacks.add((SignalCallback) msg.obj); + } else { + mSignalCallbacks.remove((SignalCallback) msg.obj); + } + break; + } + } + + @Override + public void setWifiIndicators(final boolean enabled, final IconState statusIcon, + final IconState qsIcon, final boolean activityIn, final boolean activityOut, + final String description) { + post(new Runnable() { + @Override + public void run() { + for (SignalCallback callback : mSignalCallbacks) { + callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut, + description); + } + } + }); + } + + @Override + public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon, + final int darkStatusIcon, final int statusType, final int qsType, + final boolean activityIn, final boolean activityOut, + final String typeContentDescription, final String description, final boolean isWide, + final int subId) { + post(new Runnable() { + @Override + public void run() { + for (SignalCallback signalCluster : mSignalCallbacks) { + signalCluster.setMobileDataIndicators(statusIcon, qsIcon, darkStatusIcon, + statusType, qsType, activityIn, activityOut, typeContentDescription, + description, isWide, subId); + } + } + }); + } + + @Override + public void setSubs(List<SubscriptionInfo> subs) { + obtainMessage(MSG_SUBS_CHANGED, subs).sendToTarget(); + } + + @Override + public void setNoSims(boolean show) { + obtainMessage(MSG_NO_SIM_VISIBLE_CHANGED, show ? 1 : 0, 0).sendToTarget(); + } + + @Override + public void setMobileDataEnabled(boolean enabled) { + obtainMessage(MSG_MOBILE_DATA_ENABLED_CHANGED, enabled ? 1 : 0, 0).sendToTarget(); + } + + @Override + public void setEmergencyCallsOnly(boolean emergencyOnly) { + obtainMessage(MSG_EMERGENCE_CHANGED, emergencyOnly ? 1 : 0, 0).sendToTarget(); + } + + @Override + public void setEthernetIndicators(IconState icon) { + obtainMessage(MSG_ETHERNET_CHANGED, icon).sendToTarget();; + } + + @Override + public void setIsAirplaneMode(IconState icon) { + obtainMessage(MSG_AIRPLANE_MODE_CHANGED, icon).sendToTarget();; + } + + public void setListening(EmergencyListener listener, boolean listening) { + obtainMessage(MSG_ADD_REMOVE_EMERGENCY, listening ? 1 : 0, 0, listener).sendToTarget(); + } + + public void setListening(SignalCallback listener, boolean listening) { + obtainMessage(MSG_ADD_REMOVE_SIGNAL, listening ? 1 : 0, 0, listener).sendToTarget(); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java index 9c044c4..bd36462 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java @@ -18,22 +18,18 @@ package com.android.systemui.statusbar.policy; import android.content.Context; import android.net.NetworkCapabilities; -import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; -import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster; +import com.android.systemui.statusbar.policy.NetworkController.IconState; -import java.util.List; -import java.util.Objects; +import java.util.BitSet; public class EthernetSignalController extends SignalController<SignalController.State, SignalController.IconGroup> { public EthernetSignalController(Context context, - List<NetworkSignalChangedCallback> signalCallbacks, - List<SignalCluster> signalClusters, NetworkControllerImpl networkController) { + CallbackHandler callbackHandler, NetworkControllerImpl networkController) { super("EthernetSignalController", context, NetworkCapabilities.TRANSPORT_ETHERNET, - signalCallbacks, signalClusters, networkController); + callbackHandler, networkController); mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup( "Ethernet Icons", EthernetIcons.ETHERNET_ICONS, @@ -44,25 +40,23 @@ public class EthernetSignalController extends } @Override + public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) { + mCurrentState.connected = connectedTransports.get(mTransportType); + super.updateConnectivity(connectedTransports, validatedTransports); + } + + @Override public void notifyListeners() { boolean ethernetVisible = mCurrentState.connected; String contentDescription = getStringIfExists(getContentDescription()); // TODO: wire up data transfer using WifiSignalPoller. - int signalClustersLength = mSignalClusters.size(); - for (int i = 0; i < signalClustersLength; i++) { - mSignalClusters.get(i).setEthernetIndicators(ethernetVisible, getCurrentIconId(), - contentDescription); - } + mCallbackHandler.setEthernetIndicators(new IconState(ethernetVisible, getCurrentIconId(), + contentDescription)); } @Override public SignalController.State cleanState() { return new SignalController.State(); } - - public void setConnected(boolean connected) { - mCurrentState.connected = connected; - notifyListenersIfNecessary(); - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 22bf47c..0d59953 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.content.Context; import android.content.Intent; import android.net.NetworkCapabilities; +import android.os.Looper; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -31,12 +32,11 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; +import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config; -import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster; import java.io.PrintWriter; -import java.util.List; +import java.util.BitSet; import java.util.Objects; @@ -66,17 +66,17 @@ public class MobileSignalController extends SignalController< // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't // need listener lists anymore. public MobileSignalController(Context context, Config config, boolean hasMobileData, - TelephonyManager phone, List<NetworkSignalChangedCallback> signalCallbacks, - List<SignalCluster> signalClusters, NetworkControllerImpl networkController, - SubscriptionInfo info) { + TelephonyManager phone, CallbackHandler callbackHandler, + NetworkControllerImpl networkController, SubscriptionInfo info, Looper receiverLooper) { super("MobileSignalController(" + info.getSubscriptionId() + ")", context, - NetworkCapabilities.TRANSPORT_CELLULAR, signalCallbacks, signalClusters, + NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler, networkController); mNetworkToIconLookup = new SparseArray<>(); mConfig = config; mPhone = phone; mSubscriptionInfo = info; - mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId()); + mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(), + receiverLooper); mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator); mNetworkNameDefault = getStringIfExists( com.android.internal.R.string.lockscreen_carrier_default); @@ -106,13 +106,13 @@ public class MobileSignalController extends SignalController< notifyListenersIfNecessary(); } - public void setInetCondition(int inetCondition, int inetConditionForNetwork) { - // For mobile data, use general inet condition for phone signal indexing, - // and network specific for data indexing (I think this might be a bug, but - // keeping for now). - // TODO: Update with explanation of why. - mCurrentState.inetForNetwork = inetConditionForNetwork; - setInetCondition(inetCondition); + @Override + public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) { + boolean isValidated = validatedTransports.get(mTransportType); + mCurrentState.isDefault = connectedTransports.get(mTransportType); + // Only show this as not having connectivity if we are default. + mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0; + notifyListenersIfNecessary(); } public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) { @@ -196,44 +196,33 @@ public class MobileSignalController extends SignalController< String contentDescription = getStringIfExists(getContentDescription()); String dataContentDescription = getStringIfExists(icons.mDataContentDescription); - boolean showDataIcon = mCurrentState.dataConnected && mCurrentState.inetForNetwork != 0 + // Show icon in QS when we are connected or need to show roaming. + boolean showDataIcon = mCurrentState.dataConnected || mCurrentState.iconGroup == TelephonyIcons.ROAMING; + IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode, + getCurrentIconId(), contentDescription); + int qsTypeIcon = 0; + IconState qsIcon = null; + String description = null; // Only send data sim callbacks to QS. if (mCurrentState.dataSim) { - int qsTypeIcon = showDataIcon ? icons.mQsDataType[mCurrentState.inetForNetwork] : 0; - int length = mSignalsChangedCallbacks.size(); - for (int i = 0; i < length; i++) { - mSignalsChangedCallbacks.get(i).onMobileDataSignalChanged(mCurrentState.enabled - && !mCurrentState.isEmergency, - getQsCurrentIconId(), contentDescription, - qsTypeIcon, - mCurrentState.dataConnected - && !mCurrentState.carrierNetworkChangeMode - && mCurrentState.activityIn, - mCurrentState.dataConnected - && !mCurrentState.carrierNetworkChangeMode - && mCurrentState.activityOut, - dataContentDescription, - mCurrentState.isEmergency ? null : mCurrentState.networkName, - // Only wide if actually showing something. - icons.mIsWide && qsTypeIcon != 0); - } - } + qsTypeIcon = showDataIcon ? icons.mQsDataType : 0; + qsIcon = new IconState(mCurrentState.enabled + && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription); + description = mCurrentState.isEmergency ? null : mCurrentState.networkName; + } + boolean activityIn = mCurrentState.dataConnected + && !mCurrentState.carrierNetworkChangeMode + && mCurrentState.activityIn; + boolean activityOut = mCurrentState.dataConnected + && !mCurrentState.carrierNetworkChangeMode + && mCurrentState.activityOut; + showDataIcon &= mCurrentState.isDefault; int typeIcon = showDataIcon ? icons.mDataType : 0; - int signalClustersLength = mSignalClusters.size(); - for (int i = 0; i < signalClustersLength; i++) { - mSignalClusters.get(i).setMobileDataIndicators( - mCurrentState.enabled && !mCurrentState.airplaneMode, - getCurrentIconId(), - getCurrentDarkIconId(), - typeIcon, - contentDescription, - dataContentDescription, - // Only wide if actually showing something. - icons.mIsWide && typeIcon != 0, - mSubscriptionInfo.getSubscriptionId()); - } + mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, getCurrentDarkIconId(), + typeIcon, qsTypeIcon, activityIn, activityOut, dataContentDescription, description, + icons.mIsWide, mSubscriptionInfo.getSubscriptionId()); } private int getCurrentDarkIconId() { @@ -425,8 +414,8 @@ public class MobileSignalController extends SignalController< } class MobilePhoneStateListener extends PhoneStateListener { - public MobilePhoneStateListener(int subId) { - super(subId); + public MobilePhoneStateListener(int subId, Looper looper) { + super(subId, looper); } @Override @@ -483,12 +472,12 @@ public class MobileSignalController extends SignalController< final int mDataContentDescription; // mContentDescriptionDataType final int mDataType; final boolean mIsWide; - final int[] mQsDataType; + final int mQsDataType; public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc, int sbNullState, int qsNullState, int sbDiscState, int qsDiscState, int discContentDesc, int dataContentDesc, int dataType, boolean isWide, - int[] qsDataType) { + int qsDataType) { this(name, sbIcons, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState, sbDiscState, qsDiscState, discContentDesc, dataContentDesc, dataType, isWide, qsDataType); @@ -497,7 +486,7 @@ public class MobileSignalController extends SignalController< public MobileIconGroup(String name, int[][] sbIcons, int[][] sbDarkIcons, int[][] qsIcons, int[] contentDesc, int sbNullState, int qsNullState, int sbDiscState, int sbDarkDiscState, int qsDiscState, int discContentDesc, int dataContentDesc, - int dataType, boolean isWide, int[] qsDataType) { + int dataType, boolean isWide, int qsDataType) { super(name, sbIcons, sbDarkIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState, sbDarkDiscState, qsDiscState, discContentDesc); mDataContentDescription = dataContentDesc; @@ -515,7 +504,7 @@ public class MobileSignalController extends SignalController< boolean isEmergency; boolean airplaneMode; boolean carrierNetworkChangeMode; - int inetForNetwork; + boolean isDefault; @Override public void copyFrom(State s) { @@ -525,7 +514,7 @@ public class MobileSignalController extends SignalController< networkName = state.networkName; networkNameData = state.networkNameData; dataConnected = state.dataConnected; - inetForNetwork = state.inetForNetwork; + isDefault = state.isDefault; isEmergency = state.isEmergency; airplaneMode = state.airplaneMode; carrierNetworkChangeMode = state.carrierNetworkChangeMode; @@ -539,7 +528,7 @@ public class MobileSignalController extends SignalController< builder.append("networkName=").append(networkName).append(','); builder.append("networkNameData=").append(networkNameData).append(','); builder.append("dataConnected=").append(dataConnected).append(','); - builder.append("inetForNetwork=").append(inetForNetwork).append(','); + builder.append("isDefault=").append(isDefault).append(','); builder.append("isEmergency=").append(isEmergency).append(','); builder.append("airplaneMode=").append(airplaneMode).append(','); builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode); @@ -555,7 +544,7 @@ public class MobileSignalController extends SignalController< && ((MobileState) o).isEmergency == isEmergency && ((MobileState) o).airplaneMode == airplaneMode && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode - && ((MobileState) o).inetForNetwork == inetForNetwork; + && ((MobileState) o).isDefault == isDefault; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 9212837..070ca63 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -16,7 +16,9 @@ package com.android.systemui.statusbar.policy; +import android.content.Context; import android.content.Intent; +import android.telephony.SubscriptionInfo; import com.android.settingslib.wifi.AccessPoint; @@ -25,25 +27,45 @@ import java.util.List; public interface NetworkController { boolean hasMobileDataFeature(); - void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb); - void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb); + void addSignalCallback(SignalCallback cb); + void removeSignalCallback(SignalCallback cb); void setWifiEnabled(boolean enabled); void onUserSwitched(int newUserId); AccessPointController getAccessPointController(); MobileDataController getMobileDataController(); - public interface NetworkSignalChangedCallback { - void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, - boolean activityIn, boolean activityOut, - String wifiSignalContentDescriptionId, String description); - void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId, - String mobileSignalContentDescriptionId, int dataTypeIconId, - boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description, - boolean isDataTypeIconWide); - void onNoSimVisibleChanged(boolean visible); - void onAirplaneModeChanged(boolean enabled); - void onMobileDataEnabled(boolean enabled); + public interface SignalCallback { + void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description); + + void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int darkStatusIcon, + int statusType, int qsType, boolean activityIn, boolean activityOut, + String typeContentDescription, String description, boolean isWide, int subId); + void setSubs(List<SubscriptionInfo> subs); + void setNoSims(boolean show); + + void setEthernetIndicators(IconState icon); + + void setIsAirplaneMode(IconState icon); + + void setMobileDataEnabled(boolean enabled); + } + + public static class IconState { + public final boolean visible; + public final int icon; + public final String contentDescription; + + public IconState(boolean visible, int icon, String contentDescription) { + this.visible = visible; + this.icon = icon; + this.contentDescription = contentDescription; + } + + public IconState(boolean visible, int icon, int contentDescription, + Context context) { + this(visible, icon, context.getString(contentDescription)); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 92e0365..e8957f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -28,6 +28,7 @@ import android.net.NetworkCapabilities; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Handler; import android.os.Looper; import android.provider.Settings; import android.telephony.SubscriptionInfo; @@ -36,6 +37,7 @@ import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import android.util.MathUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.PhoneConstants; @@ -61,7 +63,7 @@ public class NetworkControllerImpl extends BroadcastReceiver static final String TAG = "NetworkController"; static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // additional diagnostics, but not logspew - static final boolean CHATTY = Log.isLoggable(TAG + ".Chat", Log.DEBUG); + static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG); private final Context mContext; private final TelephonyManager mPhone; @@ -99,20 +101,19 @@ public class NetworkControllerImpl extends BroadcastReceiver private boolean mHasNoSims; private Locale mLocale = null; // This list holds our ordering. - private List<SubscriptionInfo> mCurrentSubscriptions - = new ArrayList<SubscriptionInfo>(); - - // All the callbacks. - private ArrayList<EmergencyListener> mEmergencyListeners = new ArrayList<EmergencyListener>(); - private ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>(); - private ArrayList<NetworkSignalChangedCallback> mSignalsChangedCallbacks = - new ArrayList<NetworkSignalChangedCallback>(); + private List<SubscriptionInfo> mCurrentSubscriptions = new ArrayList<>(); + @VisibleForTesting boolean mListening; // The current user ID. private int mCurrentUserId; + // Handler that all broadcasts are received on. + private final Handler mReceiverHandler; + // Handler that all callbacks are made on. + private final CallbackHandler mCallbackHandler; + /** * Construct this controller object and register for updates. */ @@ -120,20 +121,24 @@ public class NetworkControllerImpl extends BroadcastReceiver this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE), (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE), (WifiManager) context.getSystemService(Context.WIFI_SERVICE), - SubscriptionManager.from(context), Config.readConfig(context), + SubscriptionManager.from(context), Config.readConfig(context), bgLooper, + new CallbackHandler(), new AccessPointControllerImpl(context, bgLooper), new MobileDataControllerImpl(context)); - registerListeners(); + mReceiverHandler.post(mRegisterListeners); } @VisibleForTesting NetworkControllerImpl(Context context, ConnectivityManager connectivityManager, TelephonyManager telephonyManager, WifiManager wifiManager, - SubscriptionManager subManager, Config config, + SubscriptionManager subManager, Config config, Looper bgLooper, + CallbackHandler callbackHandler, AccessPointControllerImpl accessPointController, MobileDataControllerImpl mobileDataController) { mContext = context; mConfig = config; + mReceiverHandler = new Handler(bgLooper); + mCallbackHandler = callbackHandler; mSubscriptionManager = subManager; mConnectivityManager = connectivityManager; @@ -141,7 +146,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); // telephony - mPhone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + mPhone = telephonyManager; // wifi mWifiManager = wifiManager; @@ -154,14 +159,13 @@ public class NetworkControllerImpl extends BroadcastReceiver mMobileDataController.setCallback(new MobileDataControllerImpl.Callback() { @Override public void onMobileDataEnabled(boolean enabled) { - notifyMobileDataEnabled(enabled); + mCallbackHandler.setMobileDataEnabled(enabled); } }); mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature, - mSignalsChangedCallbacks, mSignalClusters, this); + mCallbackHandler, this); - mEthernetSignalController = new EthernetSignalController(mContext, mSignalsChangedCallbacks, - mSignalClusters, this); + mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this); // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it updateAirplaneMode(true /* force callback */); @@ -186,7 +190,7 @@ public class NetworkControllerImpl extends BroadcastReceiver filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); - mContext.registerReceiver(this, filter); + mContext.registerReceiver(this, filter, null, mReceiverHandler); mListening = true; updateMobileControllers(); @@ -216,15 +220,8 @@ public class NetworkControllerImpl extends BroadcastReceiver } public void addEmergencyListener(EmergencyListener listener) { - mEmergencyListeners.add(listener); - listener.setEmergencyCallsOnly(isEmergencyOnly()); - } - - private void notifyMobileDataEnabled(boolean enabled) { - final int length = mSignalsChangedCallbacks.size(); - for (int i = 0; i < length; i++) { - mSignalsChangedCallbacks.get(i).onMobileDataEnabled(enabled); - } + mCallbackHandler.setListening(listener, true); + mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly()); } public boolean hasMobileDataFeature() { @@ -276,19 +273,15 @@ public class NetworkControllerImpl extends BroadcastReceiver * so we should recheck and send out the state to listeners. */ void recalculateEmergency() { - final boolean emergencyOnly = isEmergencyOnly(); - final int length = mEmergencyListeners.size(); - for (int i = 0; i < length; i++) { - mEmergencyListeners.get(i).setEmergencyCallsOnly(emergencyOnly); - } + mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly()); } - public void addSignalCluster(SignalCluster cluster) { - mSignalClusters.add(cluster); - cluster.setSubs(mCurrentSubscriptions); - cluster.setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON, - R.string.accessibility_airplane_mode); - cluster.setNoSims(mHasNoSims); + public void addSignalCallback(SignalCallback cb) { + mCallbackHandler.setListening(cb, true); + mCallbackHandler.setSubs(mCurrentSubscriptions); + mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode, + TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext)); + mCallbackHandler.setNoSims(mHasNoSims); mWifiSignalController.notifyListeners(); mEthernetSignalController.notifyListeners(); for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { @@ -296,19 +289,9 @@ public class NetworkControllerImpl extends BroadcastReceiver } } - public void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) { - mSignalsChangedCallbacks.add(cb); - cb.onAirplaneModeChanged(mAirplaneMode); - cb.onNoSimVisibleChanged(mHasNoSims); - mWifiSignalController.notifyListeners(); - mEthernetSignalController.notifyListeners(); - for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { - mobileSignalController.notifyListeners(); - } - } - - public void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) { - mSignalsChangedCallbacks.remove(cb); + @Override + public void removeSignalCallback(SignalCallback cb) { + mCallbackHandler.setListening(cb, false); } @Override @@ -427,10 +410,7 @@ public class NetworkControllerImpl extends BroadcastReceiver : lhs.getSimSlotIndex() - rhs.getSimSlotIndex(); } }); - final int length = mSignalClusters.size(); - for (int i = 0; i < length; i++) { - mSignalClusters.get(i).setSubs(subscriptions); - } + mCallbackHandler.setSubs(subscriptions); mCurrentSubscriptions = subscriptions; HashMap<Integer, MobileSignalController> cachedControllers = @@ -444,8 +424,8 @@ public class NetworkControllerImpl extends BroadcastReceiver mMobileSignalControllers.put(subId, cachedControllers.remove(subId)); } else { MobileSignalController controller = new MobileSignalController(mContext, mConfig, - mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks, mSignalClusters, - this, subscriptions.get(i)); + mHasMobileDataFeature, mPhone, mCallbackHandler, + this, subscriptions.get(i), mReceiverHandler.getLooper()); mMobileSignalControllers.put(subId, controller); if (subscriptions.get(i).getSimSlotIndex() == 0) { mDefaultSignalController = controller; @@ -521,17 +501,9 @@ public class NetworkControllerImpl extends BroadcastReceiver * notifyAllListeners. */ private void notifyListeners() { - int length = mSignalClusters.size(); - for (int i = 0; i < length; i++) { - mSignalClusters.get(i).setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON, - R.string.accessibility_airplane_mode); - mSignalClusters.get(i).setNoSims(mHasNoSims); - } - int signalsChangedLength = mSignalsChangedCallbacks.size(); - for (int i = 0; i < signalsChangedLength; i++) { - mSignalsChangedCallbacks.get(i).onAirplaneModeChanged(mAirplaneMode); - mSignalsChangedCallbacks.get(i).onNoSimVisibleChanged(mHasNoSims); - } + mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode, + TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext)); + mCallbackHandler.setNoSims(mHasNoSims); } /** @@ -566,17 +538,10 @@ public class NetworkControllerImpl extends BroadcastReceiver private void pushConnectivityToSignals() { // We want to update all the icons, all at once, for any condition change for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { - mobileSignalController.setInetCondition( - mInetCondition ? 1 : 0, - mValidatedTransports.get(mobileSignalController.getTransportType()) ? 1 : 0); + mobileSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports); } - mWifiSignalController.setInetCondition( - mValidatedTransports.get(mWifiSignalController.getTransportType()) ? 1 : 0); - - mEthernetSignalController.setConnected( - mConnectedTransports.get(mEthernetSignalController.getTransportType())); - mEthernetSignalController.setInetCondition( - mValidatedTransports.get(mEthernetSignalController.getTransportType()) ? 1 : 0); + mWifiSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports); + mEthernetSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { @@ -609,7 +574,7 @@ public class NetworkControllerImpl extends BroadcastReceiver } private boolean mDemoMode; - private int mDemoInetCondition; + private boolean mDemoInetCondition; private WifiSignalController.WifiState mDemoWifiState; @Override @@ -618,7 +583,7 @@ public class NetworkControllerImpl extends BroadcastReceiver if (DEBUG) Log.d(TAG, "Entering demo mode"); unregisterListeners(); mDemoMode = true; - mDemoInetCondition = mInetCondition ? 1 : 0; + mDemoInetCondition = mInetCondition; mDemoWifiState = mWifiSignalController.getState(); } else if (mDemoMode && command.equals(COMMAND_EXIT)) { if (DEBUG) Log.d(TAG, "Exiting demo mode"); @@ -630,24 +595,30 @@ public class NetworkControllerImpl extends BroadcastReceiver controller.resetLastState(); } mWifiSignalController.resetLastState(); - registerListeners(); + mReceiverHandler.post(mRegisterListeners); notifyAllListeners(); } else if (mDemoMode && command.equals(COMMAND_NETWORK)) { String airplane = args.getString("airplane"); if (airplane != null) { boolean show = airplane.equals("show"); - int length = mSignalClusters.size(); - for (int i = 0; i < length; i++) { - mSignalClusters.get(i).setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON, - R.string.accessibility_airplane_mode); - } + mCallbackHandler.setIsAirplaneMode(new IconState(show, + TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, + mContext)); } String fully = args.getString("fully"); if (fully != null) { - mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0; - mWifiSignalController.setInetCondition(mDemoInetCondition); + mDemoInetCondition = Boolean.parseBoolean(fully); + BitSet connected = new BitSet(); + + if (mDemoInetCondition) { + connected.set(mWifiSignalController.mTransportType); + } + mWifiSignalController.updateConnectivity(connected, connected); for (MobileSignalController controller : mMobileSignalControllers.values()) { - controller.setInetCondition(mDemoInetCondition, mDemoInetCondition); + if (mDemoInetCondition) { + connected.set(controller.mTransportType); + } + controller.updateConnectivity(connected, connected); } } String wifi = args.getString("wifi"); @@ -664,32 +635,21 @@ public class NetworkControllerImpl extends BroadcastReceiver } String sims = args.getString("sims"); if (sims != null) { - int num = Integer.parseInt(sims); - List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>(); + int num = MathUtils.constrain(Integer.parseInt(sims), 1, 8); + List<SubscriptionInfo> subs = new ArrayList<>(); if (num != mMobileSignalControllers.size()) { mMobileSignalControllers.clear(); int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax(); for (int i = start /* get out of normal index range */; i < start + num; i++) { - SubscriptionInfo info = new SubscriptionInfo(i, "", i, "", "", 0, 0, "", 0, - null, 0, 0, ""); - subs.add(info); - mMobileSignalControllers.put(i, new MobileSignalController(mContext, - mConfig, mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks, - mSignalClusters, this, info)); + subs.add(addSignalController(i, i)); } } - final int n = mSignalClusters.size(); - for (int i = 0; i < n; i++) { - mSignalClusters.get(i).setSubs(subs); - } + mCallbackHandler.setSubs(subs); } String nosim = args.getString("nosim"); if (nosim != null) { boolean show = nosim.equals("show"); - final int n = mSignalClusters.size(); - for (int i = 0; i < n; i++) { - mSignalClusters.get(i).setNoSims(show); - } + mCallbackHandler.setNoSims(show); } String mobile = args.getString("mobile"); if (mobile != null) { @@ -697,6 +657,16 @@ public class NetworkControllerImpl extends BroadcastReceiver String datatype = args.getString("datatype"); String slotString = args.getString("slot"); int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString); + slot = MathUtils.constrain(slot, 0, 8); + // Ensure we have enough sim slots + List<SubscriptionInfo> subs = new ArrayList<>(); + while (mMobileSignalControllers.size() <= slot) { + int nextSlot = mMobileSignalControllers.size(); + subs.add(addSignalController(nextSlot, nextSlot)); + } + if (!subs.isEmpty()) { + mCallbackHandler.setSubs(subs); + } // Hack to index linearly for easy use. MobileSignalController controller = mMobileSignalControllers .values().toArray(new MobileSignalController[0])[slot]; @@ -733,6 +703,15 @@ public class NetworkControllerImpl extends BroadcastReceiver } } + private SubscriptionInfo addSignalController(int id, int simSlotIndex) { + SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0, + null, 0, 0, ""); + mMobileSignalControllers.put(id, new MobileSignalController(mContext, + mConfig, mHasMobileDataFeature, mPhone, mCallbackHandler, this, info, + mReceiverHandler.getLooper())); + return info; + } + private final OnSubscriptionsChangedListener mSubscriptionListener = new OnSubscriptionsChangedListener() { @Override @@ -741,28 +720,21 @@ public class NetworkControllerImpl extends BroadcastReceiver }; }; - public interface SignalCluster { - void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription); - - void setMobileDataIndicators(boolean visible, int strengthIcon, int darkStrengthIcon, - int typeIcon, String contentDescription, String typeContentDescription, - boolean isTypeIconWide, int subId); - void setSubs(List<SubscriptionInfo> subs); - void setNoSims(boolean show); - - void setEthernetIndicators(boolean visible, int icon, String contentDescription); - - void setIsAirplaneMode(boolean is, int airplaneIcon, int contentDescription); - } + /** + * Used to register listeners from the BG Looper, this way the PhoneStateListeners that + * get created will also run on the BG Looper. + */ + private final Runnable mRegisterListeners = new Runnable() { + @Override + public void run() { + registerListeners(); + } + }; public interface EmergencyListener { void setEmergencyCallsOnly(boolean emergencyOnly); } - public interface CarrierLabelListener { - void setCarrierLabel(String label); - } - @VisibleForTesting static class Config { boolean showAtLeast3G = false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java new file mode 100644 index 0000000..83a7d3d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.policy; + +import android.telephony.SubscriptionInfo; + +import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; + +import java.util.List; + + +/** + * Provides empty implementations of SignalCallback for those that only want some of + * the callbacks. + */ +public class SignalCallbackAdapter implements SignalCallback { + + @Override + public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description) { + } + + @Override + public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, + int darkStatusIcon, int statusType, int qsType, boolean activityIn, + boolean activityOut, String typeContentDescription, String description, + boolean isWide, int subId) { + } + + @Override + public void setSubs(List<SubscriptionInfo> subs) { + } + + @Override + public void setNoSims(boolean show) { + } + + @Override + public void setEthernetIndicators(IconState icon) { + } + + @Override + public void setIsAirplaneMode(IconState icon) { + } + + @Override + public void setMobileDataEnabled(boolean enabled) { + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java index f3322a1..e6ca646 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java @@ -21,11 +21,8 @@ import android.content.Context; import android.text.format.DateFormat; import android.util.Log; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; -import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster; - import java.io.PrintWriter; -import java.util.List; +import java.util.BitSet; /** @@ -49,24 +46,22 @@ public abstract class SignalController<T extends SignalController.State, // The owner of the SignalController (i.e. NetworkController will maintain the following // lists and call notifyListeners whenever the list has changed to ensure everyone // is aware of current state. - protected final List<NetworkSignalChangedCallback> mSignalsChangedCallbacks; - protected final List<SignalCluster> mSignalClusters; protected final NetworkControllerImpl mNetworkController; + protected final CallbackHandler mCallbackHandler; + // Save the previous HISTORY_SIZE states for logging. private final State[] mHistory; // Where to copy the next state into. private int mHistoryIndex; - public SignalController(String tag, Context context, int type, - List<NetworkSignalChangedCallback> signalCallbacks, - List<SignalCluster> signalClusters, NetworkControllerImpl networkController) { + public SignalController(String tag, Context context, int type, CallbackHandler callbackHandler, + NetworkControllerImpl networkController) { mTag = TAG + "." + tag; mNetworkController = networkController; mTransportType = type; mContext = context; - mSignalsChangedCallbacks = signalCallbacks; - mSignalClusters = signalClusters; + mCallbackHandler = callbackHandler; mCurrentState = cleanState(); mLastState = cleanState(); if (RECORD_HISTORY) { @@ -81,12 +76,8 @@ public abstract class SignalController<T extends SignalController.State, return mCurrentState; } - public int getTransportType() { - return mTransportType; - } - - public void setInetCondition(int inetCondition) { - mCurrentState.inetCondition = inetCondition; + public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) { + mCurrentState.inetCondition = validatedTransports.get(mTransportType) ? 1 : 0; notifyListenersIfNecessary(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index 053feb12..fa4d464 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -104,10 +104,7 @@ class TelephonyIcons { R.drawable.ic_qs_signal_carrier_network_change_animation } }; - static final int[] QS_DATA_R = { - R.drawable.ic_qs_signal_r, - R.drawable.ic_qs_signal_r - }; + static final int QS_DATA_R = R.drawable.ic_qs_signal_r; //***** Data connection icons @@ -123,10 +120,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_g } }; - static final int[] QS_DATA_G = { - R.drawable.ic_qs_signal_g, - R.drawable.ic_qs_signal_g - }; + static final int QS_DATA_G = R.drawable.ic_qs_signal_g; static final int[][] DATA_3G = { { R.drawable.stat_sys_data_fully_connected_3g, @@ -139,10 +133,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_3g } }; - static final int[] QS_DATA_3G = { - R.drawable.ic_qs_signal_3g, - R.drawable.ic_qs_signal_3g - }; + static final int QS_DATA_3G = R.drawable.ic_qs_signal_3g; static final int[][] DATA_E = { { R.drawable.stat_sys_data_fully_connected_e, @@ -155,10 +146,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_e } }; - static final int[] QS_DATA_E = { - R.drawable.ic_qs_signal_e, - R.drawable.ic_qs_signal_e - }; + static final int QS_DATA_E = R.drawable.ic_qs_signal_e; //3.5G static final int[][] DATA_H = { @@ -172,10 +160,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_h } }; - static final int[] QS_DATA_H = { - R.drawable.ic_qs_signal_h, - R.drawable.ic_qs_signal_h - }; + static final int QS_DATA_H = R.drawable.ic_qs_signal_h; //CDMA // Use 3G icons for EVDO data and 1x icons for 1XRTT data @@ -190,10 +175,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_1x } }; - static final int[] QS_DATA_1X = { - R.drawable.ic_qs_signal_1x, - R.drawable.ic_qs_signal_1x - }; + static final int QS_DATA_1X = R.drawable.ic_qs_signal_1x; // LTE and eHRPD static final int[][] DATA_4G = { @@ -207,10 +189,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_4g } }; - static final int[] QS_DATA_4G = { - R.drawable.ic_qs_signal_4g, - R.drawable.ic_qs_signal_4g - }; + static final int QS_DATA_4G = R.drawable.ic_qs_signal_4g; // LTE branded "LTE" static final int[][] DATA_LTE = { @@ -224,10 +203,7 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_lte } }; - static final int[] QS_DATA_LTE = { - R.drawable.ic_qs_signal_lte, - R.drawable.ic_qs_signal_lte - }; + static final int QS_DATA_LTE = R.drawable.ic_qs_signal_lte; static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode; static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam; @@ -264,7 +240,7 @@ class TelephonyIcons { R.string.accessibility_carrier_network_change_mode, 0, false, - null + 0 ); static final MobileIconGroup THREE_G = new MobileIconGroup( @@ -291,7 +267,7 @@ class TelephonyIcons { TelephonyIcons.TELEPHONY_NO_NETWORK, TelephonyIcons.QS_TELEPHONY_NO_NETWORK, AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], - 0, 0, false, new int[2] + 0, 0, false, 0 ); static final MobileIconGroup E = new MobileIconGroup( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index a97ca50..9b1e72a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -29,8 +29,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.AsyncChannel; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; -import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster; +import com.android.systemui.statusbar.policy.NetworkController.IconState; import java.util.List; import java.util.Objects; @@ -43,10 +42,9 @@ public class WifiSignalController extends private final boolean mHasMobileData; public WifiSignalController(Context context, boolean hasMobileData, - List<NetworkSignalChangedCallback> signalCallbacks, - List<SignalCluster> signalClusters, NetworkControllerImpl networkController) { + CallbackHandler callbackHandler, NetworkControllerImpl networkController) { super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI, - signalCallbacks, signalClusters, networkController); + callbackHandler, networkController); mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mHasMobileData = hasMobileData; Handler handler = new WifiHandler(); @@ -82,19 +80,13 @@ public class WifiSignalController extends String wifiDesc = wifiVisible ? mCurrentState.ssid : null; boolean ssidPresent = wifiVisible && mCurrentState.ssid != null; String contentDescription = getStringIfExists(getContentDescription()); - int length = mSignalsChangedCallbacks.size(); - for (int i = 0; i < length; i++) { - mSignalsChangedCallbacks.get(i).onWifiSignalChanged(mCurrentState.enabled, - mCurrentState.connected, getQsCurrentIconId(), - ssidPresent && mCurrentState.activityIn, - ssidPresent && mCurrentState.activityOut, contentDescription, wifiDesc); - } - int signalClustersLength = mSignalClusters.size(); - for (int i = 0; i < signalClustersLength; i++) { - mSignalClusters.get(i).setWifiIndicators(wifiVisible, getCurrentIconId(), - contentDescription); - } + IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription); + IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(), + contentDescription); + mCallbackHandler.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon, + ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut, + wifiDesc); } /** diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java index 23813d1..ad21555 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java +++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java @@ -148,6 +148,11 @@ public class StorageNotification extends SystemUI { android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); // Kick current state into place + final List<DiskInfo> disks = mStorageManager.getDisks(); + for (DiskInfo disk : disks) { + onDiskScannedInternal(disk, disk.volumeCount); + } + final List<VolumeInfo> vols = mStorageManager.getVolumes(); for (VolumeInfo vol : vols) { onVolumeStateChangedInternal(vol); @@ -194,7 +199,7 @@ public class StorageNotification extends SystemUI { } private void onDiskScannedInternal(DiskInfo disk, int volumeCount) { - if (volumeCount == 0) { + if (volumeCount == 0 && disk.size > 0) { // No supported volumes found, give user option to format final CharSequence title = mContext.getString( R.string.ext_media_unmountable_notification_title, disk.getDescription()); diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java index 6e0ca3c..09f7074 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java @@ -312,6 +312,8 @@ public class VolumeDialog { writer.print(" mShowHeaders: "); writer.println(mShowHeaders); writer.print(" mAutomute: "); writer.println(mAutomute); writer.print(" mSilentMode: "); writer.println(mSilentMode); + writer.print(" mAccessibility.mFeedbackEnabled: "); + writer.println(mAccessibility.mFeedbackEnabled); } private static int getImpliedLevel(SeekBar seekBar, int progress) { @@ -724,7 +726,7 @@ public class VolumeDialog { } row.slider.setProgress(newProgress); } - if (mAutomute) { + if (mAutomute && mShowing) { if (vlevel == 0 && !row.ss.muted && row.stream == AudioManager.STREAM_MUSIC) { mController.setStreamMute(row.stream, true); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java index 3a8081f..c6d9e46 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java @@ -180,7 +180,7 @@ public class VolumeDialogController { pw.print(" mEnabled: "); pw.println(mEnabled); pw.print(" mDestroyed: "); pw.println(mDestroyed); pw.print(" mVolumePolicy: "); pw.println(mVolumePolicy); - pw.print(" mEnabled: "); pw.println(mEnabled); + pw.print(" mState: "); pw.println(mState.toString(4)); pw.print(" mShowDndTile: "); pw.println(mShowDndTile); pw.print(" mHasVibrator: "); pw.println(mHasVibrator); pw.print(" mRemoteStreams: "); pw.println(mMediaSessionsCallbacksW.mRemoteStreams @@ -960,25 +960,45 @@ public class VolumeDialogController { @Override public String toString() { + return toString(0); + } + + public String toString(int indent) { final StringBuilder sb = new StringBuilder("{"); + if (indent > 0) sep(sb, indent); for (int i = 0; i < states.size(); i++) { - if (i > 0) sb.append(','); + if (i > 0) { + sep(sb, indent); + } final int stream = states.keyAt(i); final StreamState ss = states.valueAt(i); sb.append(AudioSystem.streamToString(stream)).append(":").append(ss.level) - .append("[").append(ss.levelMin).append("..").append(ss.levelMax); + .append('[').append(ss.levelMin).append("..").append(ss.levelMax) + .append(']'); if (ss.muted) sb.append(" [MUTED]"); } - sb.append(",ringerModeExternal:").append(ringerModeExternal); - sb.append(",ringerModeInternal:").append(ringerModeInternal); - sb.append(",zenMode:").append(zenMode); - sb.append(",effectsSuppressor:").append(effectsSuppressor); - sb.append(",effectsSuppressorName:").append(effectsSuppressorName); - sb.append(",zenModeConfig:").append(zenModeConfig); - sb.append(",activeStream:").append(activeStream); + sep(sb, indent); sb.append("ringerModeExternal:").append(ringerModeExternal); + sep(sb, indent); sb.append("ringerModeInternal:").append(ringerModeInternal); + sep(sb, indent); sb.append("zenMode:").append(zenMode); + sep(sb, indent); sb.append("effectsSuppressor:").append(effectsSuppressor); + sep(sb, indent); sb.append("effectsSuppressorName:").append(effectsSuppressorName); + sep(sb, indent); sb.append("zenModeConfig:").append(zenModeConfig); + sep(sb, indent); sb.append("activeStream:").append(activeStream); + if (indent > 0) sep(sb, indent); return sb.append('}').toString(); } + private static void sep(StringBuilder sb, int indent) { + if (indent > 0) { + sb.append('\n'); + for (int i = 0; i < indent; i++) { + sb.append(' '); + } + } else { + sb.append(','); + } + } + public Condition getManualExitCondition() { return zenModeConfig != null && zenModeConfig.manualRule != null ? zenModeConfig.manualRule.condition : null; diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index 8dfa9b0..ec24d75 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Configuration; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; @@ -175,7 +176,14 @@ public class ZenModePanel extends LinearLayout { }); mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions); + } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (mZenButtons != null) { + mZenButtons.updateLocale(); + } } private void confirmZenIntroduction() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java new file mode 100644 index 0000000..c14d06f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.policy; + +import android.os.HandlerThread; +import android.telephony.SubscriptionInfo; +import android.test.AndroidTestCase; + +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener; + +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; + +public class CallbackHandlerTest extends AndroidTestCase { + + private CallbackHandler mHandler; + private HandlerThread mHandlerThread; + + @Mock + private EmergencyListener mEmengencyListener; + @Mock + private SignalCallback mSignalCallback; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mHandlerThread = new HandlerThread("TestThread"); + mHandlerThread.start(); + mHandler = new CallbackHandler(mHandlerThread.getLooper()); + + MockitoAnnotations.initMocks(this); + mHandler.setListening(mEmengencyListener, true); + mHandler.setListening(mSignalCallback, true); + } + + public void testEmergencyListener() { + mHandler.setEmergencyCallsOnly(true); + waitForCallbacks(); + + ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class); + Mockito.verify(mEmengencyListener).setEmergencyCallsOnly(captor.capture()); + assertTrue(captor.getValue()); + } + + public void testSignalCallback_setWifiIndicators() { + boolean enabled = true; + IconState status = new IconState(true, 0, ""); + IconState qs = new IconState(true, 1, ""); + boolean in = true; + boolean out = true; + String description = "Test"; + mHandler.setWifiIndicators(enabled, status, qs, in, out, description); + waitForCallbacks(); + + ArgumentCaptor<Boolean> enableArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class); + ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class); + ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class); + Mockito.verify(mSignalCallback).setWifiIndicators(enableArg.capture(), + statusArg.capture(), qsArg.capture(), inArg.capture(), outArg.capture(), + descArg.capture()); + assertEquals(enabled, (boolean) enableArg.getValue()); + assertEquals(status, statusArg.getValue()); + assertEquals(qs, qsArg.getValue()); + assertEquals(in, (boolean) inArg.getValue()); + assertEquals(out, (boolean) outArg.getValue()); + assertEquals(description, descArg.getValue()); + } + + public void testSignalCallback_setMobileDataIndicators() { + IconState status = new IconState(true, 0, ""); + IconState qs = new IconState(true, 1, ""); + int dark = 2; + boolean in = true; + boolean out = true; + String typeDescription = "Test 1"; + String description = "Test 2"; + int type = R.drawable.stat_sys_data_fully_connected_1x; + int qsType = R.drawable.ic_qs_signal_1x; + boolean wide = true; + int subId = 5; + mHandler.setMobileDataIndicators(status, qs, dark, type, qsType, in, out, typeDescription, + description, wide, subId); + waitForCallbacks(); + + ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class); + ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class); + ArgumentCaptor<Integer> darkStrengthArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<String> typeContentArg = ArgumentCaptor.forClass(String.class); + ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class); + ArgumentCaptor<Boolean> wideArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<Integer> subIdArg = ArgumentCaptor.forClass(Integer.class); + Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(), qsArg.capture(), + darkStrengthArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(), + inArg.capture(), outArg.capture(), typeContentArg.capture(), descArg.capture(), + wideArg.capture(), subIdArg.capture()); + assertEquals(status, statusArg.getValue()); + assertEquals(qs, qsArg.getValue()); + assertEquals(dark, (int) darkStrengthArg.getValue()); + assertEquals(type, (int) typeIconArg.getValue()); + assertEquals(qsType, (int) qsTypeIconArg.getValue()); + assertEquals(in, (boolean) inArg.getValue()); + assertEquals(out, (boolean) outArg.getValue()); + assertEquals(typeDescription, typeContentArg.getValue()); + assertEquals(description, descArg.getValue()); + assertEquals(wide, (boolean) wideArg.getValue()); + assertEquals(subId, (int) subIdArg.getValue()); + } + + @SuppressWarnings("unchecked") + public void testSignalCallback_setSubs() { + List<SubscriptionInfo> subs = new ArrayList<>(); + mHandler.setSubs(subs); + waitForCallbacks(); + + ArgumentCaptor<ArrayList> subsArg = ArgumentCaptor.forClass(ArrayList.class); + Mockito.verify(mSignalCallback).setSubs(subsArg.capture()); + assertTrue(subs == subsArg.getValue()); + } + + public void testSignalCallback_setNoSims() { + boolean noSims = true; + mHandler.setNoSims(noSims); + waitForCallbacks(); + + ArgumentCaptor<Boolean> noSimsArg = ArgumentCaptor.forClass(Boolean.class); + Mockito.verify(mSignalCallback).setNoSims(noSimsArg.capture()); + assertEquals(noSims, (boolean) noSimsArg.getValue()); + } + + public void testSignalCallback_setEthernetIndicators() { + IconState state = new IconState(true, R.drawable.stat_sys_ethernet, "Test Description"); + mHandler.setEthernetIndicators(state); + waitForCallbacks(); + + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); + Mockito.verify(mSignalCallback).setEthernetIndicators(iconArg.capture()); + assertEquals(state, iconArg.getValue()); + } + + public void testSignalCallback_setIsAirplaneMode() { + IconState state = new IconState(true, R.drawable.stat_sys_airplane_mode, "Test Description"); + mHandler.setIsAirplaneMode(state); + waitForCallbacks(); + + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); + Mockito.verify(mSignalCallback).setIsAirplaneMode(iconArg.capture()); + assertEquals(state, iconArg.getValue()); + } + + private void waitForCallbacks() { + mHandlerThread.quitSafely(); + try { + mHandlerThread.join(); + } catch (InterruptedException e) { + } + } + +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 29f461e..2d6bb68 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.wifi.WifiManager; +import android.os.Looper; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -31,12 +32,10 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; -import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.cdma.EriInfo; import com.android.systemui.SysuiTestCase; -import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; +import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config; -import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -59,8 +58,6 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected NetworkControllerImpl mNetworkController; protected MobileSignalController mMobileSignalController; protected PhoneStateListener mPhoneStateListener; - protected SignalCluster mSignalCluster; - protected NetworkSignalChangedCallback mNetworkSignalChangedCallback; private SignalStrength mSignalStrength; private ServiceState mServiceState; protected ConnectivityManager mMockCm; @@ -68,6 +65,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected SubscriptionManager mMockSm; protected TelephonyManager mMockTm; protected Config mConfig; + protected CallbackHandler mCallbackHandler; protected int mSubId; @@ -91,33 +89,36 @@ public class NetworkControllerBaseTest extends SysuiTestCase { mConfig = new Config(); mConfig.hspaDataDistinguishable = true; + mCallbackHandler = mock(CallbackHandler.class); mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, - mConfig, mock(AccessPointControllerImpl.class), - mock(MobileDataControllerImpl.class)); + mConfig, Looper.getMainLooper(), mCallbackHandler, + mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class)); setupNetworkController(); } protected void setupNetworkController() { // For now just pretend to be the data sim, so we can test that too. - mSubId = SubscriptionManager.getDefaultDataSubId(); + mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; SubscriptionInfo subscription = mock(SubscriptionInfo.class); List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>(); when(subscription.getSubscriptionId()).thenReturn(mSubId); subs.add(subscription); mNetworkController.setCurrentSubscriptions(subs); mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId); + mMobileSignalController.getState().dataSim = true; mPhoneStateListener = mMobileSignalController.mPhoneStateListener; - mSignalCluster = mock(SignalCluster.class); - mNetworkSignalChangedCallback = mock(NetworkSignalChangedCallback.class); - mNetworkController.addSignalCluster(mSignalCluster); - mNetworkController.addNetworkSignalChangedCallback(mNetworkSignalChangedCallback); + + // Trigger blank callbacks to always get the current state (some tests don't trigger + // changes from default state). + mNetworkController.addSignalCallback(null); } protected NetworkControllerImpl setUpNoMobileData() { when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false); NetworkControllerImpl networkControllerNoMobile = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, - mConfig, mock(AccessPointControllerImpl.class), + mConfig, Looper.getMainLooper(), mCallbackHandler, + mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class)); setupNetworkController(); @@ -144,10 +145,10 @@ public class NetworkControllerBaseTest extends SysuiTestCase { setLevel(DEFAULT_LEVEL); updateDataConnectionState(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_UMTS); - setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true); + setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, true, true); } - public void setConnectivity(int inetCondition, int networkType, boolean isConnected) { + public void setConnectivity(int networkType, boolean inetCondition, boolean isConnected) { Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION); // TODO: Separate out into several NetworkCapabilities. if (isConnected) { @@ -155,7 +156,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { } else { mNetCapabilities.removeTransportType(networkType); } - if (inetCondition != 0) { + if (inetCondition) { mNetCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); } else { mNetCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); @@ -242,34 +243,30 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected void verifyHasNoSims(boolean hasNoSimsVisible) { ArgumentCaptor<Boolean> hasNoSimsArg = ArgumentCaptor.forClass(Boolean.class); - Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setNoSims(hasNoSimsArg.capture()); - assertEquals("No sims in status bar", hasNoSimsVisible, (boolean) hasNoSimsArg.getValue()); - - Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()) - .onNoSimVisibleChanged(hasNoSimsArg.capture()); - assertEquals("No sims in quick settings", hasNoSimsVisible, - (boolean) hasNoSimsArg.getValue()); + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setNoSims(hasNoSimsArg.capture()); + assertEquals("No sims", hasNoSimsVisible, (boolean) hasNoSimsArg.getValue()); } protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean dataIn, boolean dataOut) { - ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class); ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class); ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class); - Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()) - .onMobileDataSignalChanged(visibleArg.capture(), iconArg.capture(), - ArgumentCaptor.forClass(String.class).capture(), - typeIconArg.capture(), - dataInArg.capture(), - dataOutArg.capture(), - ArgumentCaptor.forClass(String.class).capture(), - ArgumentCaptor.forClass(String.class).capture(), - ArgumentCaptor.forClass(Boolean.class).capture()); - assertEquals("Visibility in, quick settings", visible, (boolean) visibleArg.getValue()); - assertEquals("Signal icon in, quick settings", icon, (int) iconArg.getValue()); + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( + ArgumentCaptor.forClass(IconState.class).capture(), + iconArg.capture(), + ArgumentCaptor.forClass(Integer.class).capture(), + ArgumentCaptor.forClass(Integer.class).capture(), + typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(), + ArgumentCaptor.forClass(String.class).capture(), + ArgumentCaptor.forClass(String.class).capture(), + ArgumentCaptor.forClass(Boolean.class).capture(), + ArgumentCaptor.forClass(Integer.class).capture()); + IconState iconState = iconArg.getValue(); + assertEquals("Visibility in, quick settings", visible, iconState.visible); + assertEquals("Signal icon in, quick settings", icon, iconState.icon); assertEquals("Data icon in, quick settings", typeIcon, (int) typeIconArg.getValue()); assertEquals("Data direction in, in quick settings", dataIn, (boolean) dataInArg.getValue()); @@ -283,29 +280,32 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected void verifyLastMobileDataIndicators(boolean visible, int strengthIcon, int darkStrengthIcon, int typeIcon) { - ArgumentCaptor<Integer> strengthIconArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); ArgumentCaptor<Integer> darkStrengthIconArg = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class); // TODO: Verify all fields. - Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setMobileDataIndicators( - visibleArg.capture(), strengthIconArg.capture(), darkStrengthIconArg.capture(), - typeIconArg.capture(), + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( + iconArg.capture(), + ArgumentCaptor.forClass(IconState.class).capture(), + darkStrengthIconArg.capture(), typeIconArg.capture(), + ArgumentCaptor.forClass(Integer.class).capture(), + ArgumentCaptor.forClass(Boolean.class).capture(), + ArgumentCaptor.forClass(Boolean.class).capture(), ArgumentCaptor.forClass(String.class).capture(), ArgumentCaptor.forClass(String.class).capture(), ArgumentCaptor.forClass(Boolean.class).capture(), ArgumentCaptor.forClass(Integer.class).capture()); + IconState iconState = iconArg.getValue(); - assertEquals("Signal strength icon in status bar", strengthIcon, - (int) strengthIconArg.getValue()); + assertEquals("Signal strength icon in status bar", strengthIcon, iconState.icon); assertEquals("Signal strength icon (dark mode) in status bar", darkStrengthIcon, (int) darkStrengthIconArg.getValue()); assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); - assertEquals("Visibility in status bar", visible, (boolean) visibleArg.getValue()); + assertEquals("Visibility in status bar", visible, iconState.visible); } protected void assertNetworkNameEquals(String expected) { - assertEquals("Network name", expected, mNetworkController.getMobileDataNetworkName()); + assertEquals("Network name", expected, mMobileSignalController.getState().networkName); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index 3f9312d..15752e1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -1,16 +1,17 @@ package com.android.systemui.statusbar.policy; -import org.mockito.Mockito; - +import android.os.Looper; import android.telephony.TelephonyManager; +import org.mockito.Mockito; + public class NetworkControllerDataTest extends NetworkControllerBaseTest { public void test3gDataIcon() { setupDefaultSignal(); verifyDataIndicators(TelephonyIcons.DATA_3G[1][0 /* No direction */], - TelephonyIcons.QS_DATA_3G[1]); + TelephonyIcons.QS_DATA_3G); } public void testRoamingDataIcon() { @@ -22,7 +23,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyIcons.ROAMING_ICON); verifyLastQsMobileDataIndicators(true, TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL], - TelephonyIcons.QS_DATA_R[1], false, false); + TelephonyIcons.QS_DATA_R, false, false); } public void test2gDataIcon() { @@ -31,7 +32,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_GSM); verifyDataIndicators(TelephonyIcons.DATA_G[1][0 /* No direction */], - TelephonyIcons.QS_DATA_G[1]); + TelephonyIcons.QS_DATA_G); } public void testCdmaDataIcon() { @@ -40,7 +41,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_CDMA); verifyDataIndicators(TelephonyIcons.DATA_1X[1][0 /* No direction */], - TelephonyIcons.QS_DATA_1X[1]); + TelephonyIcons.QS_DATA_1X); } public void testEdgeDataIcon() { @@ -49,7 +50,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_EDGE); verifyDataIndicators(TelephonyIcons.DATA_E[1][0 /* No direction */], - TelephonyIcons.QS_DATA_E[1]); + TelephonyIcons.QS_DATA_E); } public void testLteDataIcon() { @@ -58,7 +59,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_LTE); verifyDataIndicators(TelephonyIcons.DATA_LTE[1][0 /* No direction */], - TelephonyIcons.QS_DATA_LTE[1]); + TelephonyIcons.QS_DATA_LTE); } public void testHspaDataIcon() { @@ -67,14 +68,15 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_HSPA); verifyDataIndicators(TelephonyIcons.DATA_H[1][0 /* No direction */], - TelephonyIcons.QS_DATA_H[1]); + TelephonyIcons.QS_DATA_H); } public void test4gDataIcon() { // Switch to showing 4g icon and re-initialize the NetworkController. mConfig.show4gForLte = true; mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, - mConfig, Mockito.mock(AccessPointControllerImpl.class), + mConfig, Looper.getMainLooper(), mCallbackHandler, + Mockito.mock(AccessPointControllerImpl.class), Mockito.mock(MobileDataControllerImpl.class)); setupNetworkController(); @@ -83,7 +85,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_LTE); verifyDataIndicators(TelephonyIcons.DATA_4G[1][0 /* No direction */], - TelephonyIcons.QS_DATA_4G[1]); + TelephonyIcons.QS_DATA_4G); } public void test4gDataIconConfigChange() { @@ -99,7 +101,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { mNetworkController.handleConfigurationChanged(); verifyDataIndicators(TelephonyIcons.DATA_4G[1][0 /* No direction */], - TelephonyIcons.QS_DATA_4G[1]); + TelephonyIcons.QS_DATA_4G); } public void testDataActivity() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java index 82ced9f..5d63d8d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java @@ -2,6 +2,8 @@ package com.android.systemui.statusbar.policy; import android.net.NetworkCapabilities; +import com.android.systemui.statusbar.policy.NetworkController.IconState; + import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -24,17 +26,16 @@ public class NetworkControllerEthernetTest extends NetworkControllerBaseTest { } protected void setEthernetState(boolean connected, boolean validated) { - setConnectivity(validated ? 100 : 0, NetworkCapabilities.TRANSPORT_ETHERNET, connected); + setConnectivity(NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected); } protected void verifyLastEthernetIcon(boolean visible, int icon) { - ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class); - - Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setEthernetIndicators( - visibleArg.capture(), iconArg.capture(), - ArgumentCaptor.forClass(String.class).capture()); - assertEquals("Ethernet visible, in status bar", visible, (boolean) visibleArg.getValue()); - assertEquals("Ethernet icon, in status bar", icon, (int) iconArg.getValue()); + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); + + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEthernetIndicators( + iconArg.capture()); + IconState iconState = iconArg.getValue(); + assertEquals("Ethernet visible, in status bar", visible, iconState.visible); + assertEquals("Ethernet icon, in status bar", icon, iconState.icon); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java index 389ad6f..874fdf9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java @@ -19,12 +19,13 @@ import static org.mockito.Mockito.mock; import android.content.Intent; import android.net.ConnectivityManager; +import android.net.NetworkCapabilities; +import android.os.Looper; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; -import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.systemui.R; @@ -41,8 +42,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false); // Create a new NetworkController as this is currently handled in constructor. mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, - mConfig, mock(AccessPointControllerImpl.class), - mock(MobileDataControllerImpl.class)); + mConfig, Looper.getMainLooper(), mCallbackHandler, + mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class)); setupNetworkController(); verifyLastMobileDataIndicators(false, 0, 0); @@ -61,8 +62,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false); // Create a new NetworkController as this is currently handled in constructor. mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, - mConfig, mock(AccessPointControllerImpl.class), - mock(MobileDataControllerImpl.class)); + mConfig, Looper.getMainLooper(), mCallbackHandler, + mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class)); setupNetworkController(); // No Subscriptions. @@ -79,13 +80,12 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { setLevel(testStrength); verifyLastMobileDataIndicators(true, - TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength], - DEFAULT_ICON); + TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength], DEFAULT_ICON); // Verify low inet number indexing. - setConnectivity(0, ConnectivityManager.TYPE_MOBILE, true); + setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, true); verifyLastMobileDataIndicators(true, - TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[0][testStrength], 0); + TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[0][testStrength], DEFAULT_ICON); } } @@ -154,18 +154,12 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { } } - public void testNoRoamingWithoutSignal() { + public void testNoBangWithWifi() { setupDefaultSignal(); - setCdma(); - setCdmaRoaming(true); - setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); - setDataRegState(ServiceState.STATE_OUT_OF_SERVICE); - - // This exposes the bug in b/18034542, and should be switched to the commented out - // verification below (and pass), once the bug is fixed. - verifyLastMobileDataIndicators(true, R.drawable.stat_sys_signal_null, - TelephonyIcons.ROAMING_ICON); - //verifyLastMobileDataIndicators(true, R.drawable.stat_sys_signal_null, 0 /* No Icon */); + setConnectivity(mMobileSignalController.mTransportType, false, false); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true); + + verifyLastMobileDataIndicators(true, TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][2], 0); } // Some tests of actual NetworkController code, just internals not display stuff diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java index 2e0e9a3..cecf2fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java @@ -1,11 +1,13 @@ package com.android.systemui.statusbar.policy; import android.content.Intent; -import android.net.ConnectivityManager; +import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import com.android.systemui.statusbar.policy.NetworkController.IconState; + import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -25,9 +27,9 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) { setWifiLevel(testLevel); - setConnectivity(100, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true); verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]); - setConnectivity(0, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, false, true); verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]); } } @@ -45,10 +47,10 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) { setWifiLevel(testLevel); - setConnectivity(100, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true); verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel], testSsid); - setConnectivity(0, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, false, true); verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel], testSsid); } @@ -61,7 +63,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { setWifiEnabled(true); setWifiState(true, testSsid); setWifiLevel(testLevel); - setConnectivity(100, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true); verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel], testSsid); @@ -82,13 +84,13 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { setWifiEnabled(true); setWifiState(true, testSsid); setWifiLevel(testLevel); - setConnectivity(100, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true); verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]); setupDefaultSignal(); setGsmRoaming(true); // Still be on wifi though. - setConnectivity(100, ConnectivityManager.TYPE_WIFI, true); + setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true); verifyLastMobileDataIndicators(true, TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL], TelephonyIcons.ROAMING_ICON); @@ -133,46 +135,39 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class); ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class); - Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged( - ArgumentCaptor.forClass(Boolean.class).capture(), - ArgumentCaptor.forClass(Boolean.class).capture(), - ArgumentCaptor.forClass(Integer.class).capture(), - inArg.capture(), outArg.capture(), - ArgumentCaptor.forClass(String.class).capture(), - ArgumentCaptor.forClass(String.class).capture()); + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators( + Mockito.anyBoolean(), Mockito.any(IconState.class), Mockito.any(IconState.class), + inArg.capture(), outArg.capture(), Mockito.anyString()); assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue()); assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue()); } protected void verifyLastQsWifiIcon(boolean enabled, boolean connected, int icon, String description) { + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); ArgumentCaptor<Boolean> enabledArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Boolean> connectedArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class); - Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged( - enabledArg.capture(), connectedArg.capture(), iconArg.capture(), - ArgumentCaptor.forClass(Boolean.class).capture(), - ArgumentCaptor.forClass(Boolean.class).capture(), - ArgumentCaptor.forClass(String.class).capture(), + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators( + enabledArg.capture(), Mockito.any(IconState.class), + iconArg.capture(), Mockito.anyBoolean(), + Mockito.anyBoolean(), descArg.capture()); + IconState iconState = iconArg.getValue(); assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue()); - assertEquals("WiFi connected, in quick settings", connected, - (boolean) connectedArg.getValue()); - assertEquals("WiFi signal, in quick settings", icon, (int) iconArg.getValue()); - assertEquals("WiFI desc (ssid), in quick settings", description, - (String) descArg.getValue()); + assertEquals("WiFi connected, in quick settings", connected, iconState.visible); + assertEquals("WiFi signal, in quick settings", icon, iconState.icon); + assertEquals("WiFI desc (ssid), in quick settings", description, descArg.getValue()); } protected void verifyLastWifiIcon(boolean visible, int icon) { - ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class); - - Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setWifiIndicators( - visibleArg.capture(), iconArg.capture(), - ArgumentCaptor.forClass(String.class).capture()); - assertEquals("WiFi visible, in status bar", visible, (boolean) visibleArg.getValue()); - assertEquals("WiFi signal, in status bar", icon, (int) iconArg.getValue()); + ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); + + Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators( + Mockito.anyBoolean(), iconArg.capture(), Mockito.any(IconState.class), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyString()); + IconState iconState = iconArg.getValue(); + assertEquals("WiFi visible, in status bar", visible, iconState.visible); + assertEquals("WiFi signal, in status bar", icon, iconState.icon); } } diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java index ea8b2ec..48e0582 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java @@ -21,6 +21,7 @@ import android.content.DialogInterface; import android.graphics.drawable.Drawable; import android.net.IConnectivityManager; import android.os.ServiceManager; +import android.os.UserHandle; import android.text.Html; import android.text.Html.ImageGetter; import android.util.Log; @@ -50,7 +51,7 @@ public class ConfirmDialog extends AlertActivity mService = IConnectivityManager.Stub.asInterface( ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); - if (mService.prepareVpn(mPackage, null)) { + if (mService.prepareVpn(mPackage, null, UserHandle.myUserId())) { setResult(RESULT_OK); finish(); return; @@ -94,10 +95,10 @@ public class ConfirmDialog extends AlertActivity @Override public void onClick(DialogInterface dialog, int which) { try { - if (mService.prepareVpn(null, mPackage)) { + if (mService.prepareVpn(null, mPackage, UserHandle.myUserId())) { // Authorize this app to initiate VPN connections in the future without user // intervention. - mService.setVpnPackageAuthorization(true); + mService.setVpnPackageAuthorization(mPackage, UserHandle.myUserId(), true); setResult(RESULT_OK); } } catch (Exception e) { diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java index cc8500a..76b2346 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java @@ -23,6 +23,7 @@ import android.os.Handler; import android.os.Message; import android.os.ServiceManager; import android.os.SystemClock; +import android.os.UserHandle; import android.util.Log; import android.view.View; import android.widget.TextView; @@ -63,7 +64,7 @@ public class ManageDialog extends AlertActivity implements mService = IConnectivityManager.Stub.asInterface( ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); - mConfig = mService.getVpnConfig(); + mConfig = mService.getVpnConfig(UserHandle.myUserId()); // mConfig can be null if we are a restricted user, in that case don't show this dialog if (mConfig == null) { @@ -120,10 +121,11 @@ public class ManageDialog extends AlertActivity implements if (which == DialogInterface.BUTTON_POSITIVE) { mConfig.configureIntent.send(); } else if (which == DialogInterface.BUTTON_NEUTRAL) { + final int myUserId = UserHandle.myUserId(); if (mConfig.legacy) { - mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN); + mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, myUserId); } else { - mService.prepareVpn(mConfig.user, VpnConfig.LEGACY_VPN); + mService.prepareVpn(mConfig.user, VpnConfig.LEGACY_VPN, myUserId); } } } catch (Exception e) { |