? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
- getFilesDir().getAbsolutePath(), getObbDir().getAbsolutePath(),
- getExternalFilesDir(null).getAbsolutePath(),
- Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
-
+ getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
+ getAbsolutePath(getExternalFilesDir(null)),
+ Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
+
if (mNativeHandle == 0) {
throw new IllegalArgumentException("Unable to load native library: " + path);
}
super.onCreate(savedInstanceState);
}
+ private static String getAbsolutePath(File file) {
+ return (file != null) ? file.getAbsolutePath() : null;
+ }
+
@Override
protected void onDestroy() {
mDestroyed = true;
public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";
/** {@hide} */
- public static final String ACTION_ROOTS_CHANGED = "android.provider.action.ROOTS_CHANGED";
+ public static final String ACTION_DOCUMENT_CHANGED = "android.provider.action.DOCUMENT_CHANGED";
/**
* {@link DocumentColumns#DOC_ID} value representing the root directory of a
* This signal is used to invalidate internal caches.
*/
public static void notifyRootsChanged(Context context, String authority) {
- final Intent intent = new Intent(ACTION_ROOTS_CHANGED);
+ final Intent intent = new Intent(ACTION_DOCUMENT_CHANGED);
intent.setData(buildRootsUri(authority));
context.sendBroadcast(intent);
}
}\r
}\r
\r
- SkBitmap bitmap;\r
+ // ARGB_4444 is a deprecated format, convert automatically to 8888\r
+ if (config == SkBitmap::kARGB_4444_Config) {\r
+ config = SkBitmap::kARGB_8888_Config;\r
+ }\r
\r
+ SkBitmap bitmap;\r
bitmap.setConfig(config, width, height);\r
\r
jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);\r
}\r
\r
if (jColors != NULL) {\r
- GraphicsJNI::SetPixels(env, jColors, offset, stride,\r
- 0, 0, width, height, bitmap);\r
+ GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap);\r
}\r
\r
return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, isMutable, NULL, NULL);\r
code->internalDataPath = code->internalDataPathObj.string();
env->ReleaseStringUTFChars(internalDataDir, dirStr);
- dirStr = env->GetStringUTFChars(externalDataDir, NULL);
- code->externalDataPathObj = dirStr;
+ if (externalDataDir != NULL) {
+ dirStr = env->GetStringUTFChars(externalDataDir, NULL);
+ code->externalDataPathObj = dirStr;
+ env->ReleaseStringUTFChars(externalDataDir, dirStr);
+ }
code->externalDataPath = code->externalDataPathObj.string();
- env->ReleaseStringUTFChars(externalDataDir, dirStr);
code->sdkVersion = sdkVersion;
code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
- dirStr = env->GetStringUTFChars(obbDir, NULL);
- code->obbPathObj = dirStr;
+ if (obbDir != NULL) {
+ dirStr = env->GetStringUTFChars(obbDir, NULL);
+ code->obbPathObj = dirStr;
+ env->ReleaseStringUTFChars(obbDir, dirStr);
+ }
code->obbPath = code->obbPathObj.string();
- env->ReleaseStringUTFChars(obbDir, dirStr);
jbyte* rawSavedState = NULL;
jsize rawSavedSize = 0;
<intent-filter android:priority="100">
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter android:priority="100">
<action android:name="android.intent.action.CREATE_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.OPENABLE" />
+ <data android:mimeType="*/*" />
+ </intent-filter>
+ <intent-filter android:priority="100">
+ <action android:name="android.intent.action.GET_CONTENT" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<string name="root_type_service">Services</string>
<string name="root_type_shortcut">Shortcuts</string>
<string name="root_type_device">Devices</string>
+ <string name="root_type_apps">More apps</string>
<string name="pref_advanced_devices">Display advanced devices</string>
<string name="pref_file_size">Display file size</string>
final DisplayState state = getDisplayState(DirectoryFragment.this);
mFilter = new MimePredicate(state.acceptMimes);
- final Uri contentsUri;
+ Uri contentsUri;
if (mType == TYPE_NORMAL) {
contentsUri = DocumentsContract.buildContentsUri(uri);
} else if (mType == TYPE_RECENT_OPEN) {
contentsUri = uri;
}
+ if (state.localOnly) {
+ contentsUri = DocumentsContract.setLocalOnly(contentsUri);
+ }
+
final Comparator<Document> sortOrder;
if (state.sortOrder == DisplayState.SORT_ORDER_DATE || mType == TYPE_RECENT_OPEN) {
sortOrder = new Document.DateComparator();
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
+import android.provider.DocumentsContract.DocumentColumns;
import android.util.Log;
import com.android.documentsui.model.Document;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.LinkedList;
import java.util.List;
public class DirectoryLoader extends UriDerivativeLoader<List<Document>> {
private Predicate<Document> mFilter;
private Comparator<Document> mSortOrder;
+ /**
+ * Stub result that represents an internal error.
+ */
+ public static class ExceptionResult extends LinkedList<Document> {
+ public final Exception e;
+
+ public ExceptionResult(Exception e) {
+ this.e = e;
+ }
+ }
+
public DirectoryLoader(Context context, Uri uri, int type, Predicate<Document> filter,
Comparator<Document> sortOrder) {
super(context, uri);
@Override
public List<Document> loadInBackground(Uri uri, CancellationSignal signal) {
+ try {
+ return loadInBackgroundInternal(uri, signal);
+ } catch (Exception e) {
+ return new ExceptionResult(e);
+ }
+ }
+
+ private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) {
final ArrayList<Document> result = Lists.newArrayList();
- // TODO: send selection and sorting hints to backend
final ContentResolver resolver = getContext().getContentResolver();
- final Cursor cursor = resolver.query(uri, null, null, null, null, signal);
+ final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal);
try {
while (cursor != null && cursor.moveToNext()) {
Document doc = null;
return result;
}
+
+ private String getQuerySortOrder() {
+ if (mSortOrder instanceof Document.DateComparator) {
+ return DocumentColumns.LAST_MODIFIED + " DESC";
+ } else if (mSortOrder instanceof Document.NameComparator) {
+ return DocumentColumns.DISPLAY_NAME + " ASC";
+ } else if (mSortOrder instanceof Document.SizeComparator) {
+ return DocumentColumns.SIZE + " DESC";
+ } else {
+ return null;
+ }
+ }
}
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.ClipData;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
+import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
public static final int ACTION_OPEN = 1;
public static final int ACTION_CREATE = 2;
+ public static final int ACTION_GET_CONTENT = 3;
private int mAction;
final String action = intent.getAction();
if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
mAction = ACTION_OPEN;
- mDisplayState.allowMultiple = intent.getBooleanExtra(
- Intent.EXTRA_ALLOW_MULTIPLE, false);
} else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
mAction = ACTION_CREATE;
- mDisplayState.allowMultiple = false;
+ } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
+ mAction = ACTION_GET_CONTENT;
+ }
+
+ if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
+ mDisplayState.allowMultiple = intent.getBooleanExtra(
+ Intent.EXTRA_ALLOW_MULTIPLE, false);
}
if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
mDisplayState.acceptMimes = new String[] { intent.getType() };
}
- if (MimePredicate.mimeMatches("image/*", mDisplayState.acceptMimes)) {
- mDisplayState.mode = DisplayState.MODE_GRID;
- } else {
- mDisplayState.mode = DisplayState.MODE_LIST;
- }
+ mDisplayState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
setResult(Activity.RESULT_CANCELED);
setContentView(R.layout.activity);
SaveFragment.show(getFragmentManager(), mimeType, title);
}
- RootsFragment.show(getFragmentManager());
+ if (mAction == ACTION_GET_CONTENT) {
+ final Intent moreApps = new Intent(getIntent());
+ moreApps.setComponent(null);
+ moreApps.setPackage(null);
+ RootsFragment.show(getFragmentManager(), moreApps);
+ } else {
+ RootsFragment.show(getFragmentManager(), null);
+ }
mRootsContainer = findViewById(R.id.container_roots);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setIcon(new ColorDrawable());
- if (mAction == ACTION_OPEN) {
+ if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
actionBar.setTitle(R.string.title_open);
} else if (mAction == ACTION_CREATE) {
actionBar.setTitle(R.string.title_save);
}
}
+ public void onAppPicked(ResolveInfo info) {
+ final Intent intent = new Intent(getIntent());
+ intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ intent.setComponent(new ComponentName(
+ info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
+ startActivity(intent);
+ finish();
+ }
+
public void onDocumentPicked(Document doc) {
final FragmentManager fm = getFragmentManager();
if (doc.isDirectory()) {
mStack.push(doc);
onCurrentDirectoryChanged();
- } else if (mAction == ACTION_OPEN) {
+ } else if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
// Explicit file picked, return
onFinished(doc.uri);
} else if (mAction == ACTION_CREATE) {
values.put(RecentsProvider.COL_PATH, rawStack);
resolver.insert(RecentsProvider.buildRecentCreate(), values);
- } else if (mAction == ACTION_OPEN) {
+ } else if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) {
// Remember opened items
for (Uri uri : uris) {
values.clear();
intent.setClipData(clipData);
}
- // TODO: omit WRITE and PERSIST for GET_CONTENT
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+ if (mAction == ACTION_GET_CONTENT) {
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ } else {
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+ }
setResult(Activity.RESULT_OK, intent);
finish();
public int sortOrder = SORT_ORDER_NAME;
public boolean allowMultiple = false;
public boolean showSize = false;
+ public boolean localOnly = false;
public static final int MODE_LIST = 0;
public static final int MODE_GRID = 1;
switch (sMatcher.match(uri)) {
case URI_RECENT_OPEN: {
return db.query(TABLE_RECENT_OPEN, projection,
- buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, sortOrder);
+ buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, null);
}
case URI_RECENT_CREATE: {
return db.query(TABLE_RECENT_CREATE, projection,
- buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, sortOrder);
+ buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, null);
}
case URI_RESUME: {
final String packageName = uri.getPathSegments().get(1);
sProviders.put(info.providerInfo.authority, info);
- // TODO: remove deprecated customRoots flag
- // TODO: populate roots on background thread, and cache results
- final Uri uri = DocumentsContract.buildRootsUri(providerInfo.authority);
- final Cursor cursor = context.getContentResolver()
- .query(uri, null, null, null, null);
try {
- while (cursor.moveToNext()) {
- final Root root = Root.fromCursor(context, info, cursor);
- sRoots.put(Pair.create(info.providerInfo.authority, root.rootId), root);
- sRootsList.add(root);
+ // TODO: remove deprecated customRoots flag
+ // TODO: populate roots on background thread, and cache results
+ final Uri uri = DocumentsContract.buildRootsUri(providerInfo.authority);
+ final Cursor cursor = context.getContentResolver()
+ .query(uri, null, null, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ final Root root = Root.fromCursor(context, info, cursor);
+ sRoots.put(Pair.create(info.providerInfo.authority, root.rootId), root);
+ sRootsList.add(root);
+ }
+ } finally {
+ cursor.close();
}
- } finally {
- cursor.close();
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to load some roots from " + info.providerInfo.authority
+ + ": " + e);
}
}
}
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.text.format.Formatter;
import com.android.documentsui.model.Root.RootComparator;
import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
/**
* Display list of known storage backend roots.
private ListView mList;
private SectionedRootsAdapter mAdapter;
- public static void show(FragmentManager fm) {
+ private static final String EXTRA_INCLUDE_APPS = "includeApps";
+
+ public static void show(FragmentManager fm, Intent includeApps) {
+ final Bundle args = new Bundle();
+ args.putParcelable(EXTRA_INCLUDE_APPS, includeApps);
+
final RootsFragment fragment = new RootsFragment();
+ fragment.setArguments(args);
final FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container_roots, fragment);
final View view = inflater.inflate(R.layout.fragment_roots, container, false);
mList = (ListView) view.findViewById(android.R.id.list);
-
- mAdapter = new SectionedRootsAdapter(context, RootsCache.getRoots(context));
- mList.setAdapter(mAdapter);
mList.setOnItemClickListener(mItemListener);
+ final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS);
+ mAdapter = new SectionedRootsAdapter(context, RootsCache.getRoots(context), includeApps);
+
return view;
}
super.onStart();
final Context context = getActivity();
- mAdapter.setShowAdvanced(SettingsActivity.getDisplayAdvancedDevices(context));
+ mAdapter.updateVisible(SettingsActivity.getDisplayAdvancedDevices(context));
+ mList.setAdapter(mAdapter);
}
private OnItemClickListener mItemListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- final Root root = (Root) mAdapter.getItem(position);
- ((DocumentsActivity) getActivity()).onRootPicked(root, true);
+ final DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
+ final Object item = mAdapter.getItem(position);
+ if (item instanceof Root) {
+ activity.onRootPicked((Root) item, true);
+ } else if (item instanceof ResolveInfo) {
+ activity.onAppPicked((ResolveInfo) item);
+ } else {
+ throw new IllegalStateException("Unknown root: " + item);
+ }
}
};
- public static class RootsAdapter extends ArrayAdapter<Root> implements SectionAdapter {
+ private static class RootsAdapter extends ArrayAdapter<Root> implements SectionAdapter {
private int mHeaderId;
public RootsAdapter(Context context, int headerId) {
}
}
- public static class SectionedRootsAdapter extends SectionedListAdapter {
+ private static class AppsAdapter extends ArrayAdapter<ResolveInfo> implements SectionAdapter {
+ public AppsAdapter(Context context) {
+ super(context, 0);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final Context context = parent.getContext();
+ final PackageManager pm = context.getPackageManager();
+ if (convertView == null) {
+ convertView = LayoutInflater.from(context)
+ .inflate(R.layout.item_root, parent, false);
+ }
+
+ final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+ final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+ final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+
+ final ResolveInfo info = getItem(position);
+ icon.setImageDrawable(info.loadIcon(pm));
+ title.setText(info.loadLabel(pm));
+
+ // TODO: match existing summary behavior from disambig dialog
+ summary.setVisibility(View.GONE);
+
+ return convertView;
+ }
+
+ @Override
+ public View getHeaderView(View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_root_header, parent, false);
+ }
+
+ final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+ title.setText(R.string.root_type_apps);
+
+ return convertView;
+ }
+ }
+
+ private static class SectionedRootsAdapter extends SectionedListAdapter {
private final RootsAdapter mServices;
private final RootsAdapter mShortcuts;
private final RootsAdapter mDevices;
private final RootsAdapter mDevicesAdvanced;
+ private final AppsAdapter mApps;
- public SectionedRootsAdapter(Context context, Collection<Root> roots) {
+ public SectionedRootsAdapter(Context context, Collection<Root> roots, Intent includeApps) {
mServices = new RootsAdapter(context, R.string.root_type_service);
mShortcuts = new RootsAdapter(context, R.string.root_type_shortcut);
mDevices = new RootsAdapter(context, R.string.root_type_device);
mDevicesAdvanced = new RootsAdapter(context, R.string.root_type_device);
+ mApps = new AppsAdapter(context);
for (Root root : roots) {
Log.d(TAG, "Found rootType=" + root.rootType);
}
}
+ if (includeApps != null) {
+ final PackageManager pm = context.getPackageManager();
+ final List<ResolveInfo> infos = pm.queryIntentActivities(
+ includeApps, PackageManager.MATCH_DEFAULT_ONLY);
+
+ // Omit ourselves from the list
+ for (ResolveInfo info : infos) {
+ if (!context.getPackageName().equals(info.activityInfo.packageName)) {
+ mApps.add(info);
+ }
+ }
+ }
+
final RootComparator comp = new RootComparator();
mServices.sort(comp);
mShortcuts.sort(comp);
mDevicesAdvanced.sort(comp);
}
- public void setShowAdvanced(boolean showAdvanced) {
+ public void updateVisible(boolean showAdvanced) {
clearSections();
if (mServices.getCount() > 0) {
addSection(mServices);
if (devices.getCount() > 0) {
addSection(devices);
}
+
+ if (mApps.getCount() > 0) {
+ addSection(mApps);
+ }
}
}
}
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
notifyDataSetChanged();
}
+ /**
+ * After mutating sections, you <em>must</em>
+ * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly
+ * recount view types.
+ */
public void addSection(SectionAdapter adapter) {
mSections.add(adapter);
notifyDataSetChanged();
if (position == 0) {
return false;
} else if (position < sectionSize) {
- return section.isEnabled(position);
+ return section.isEnabled(position - 1);
}
// Otherwise jump into next section
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
if (multiple.isChecked()) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
if (multiple.isChecked()) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
"text/plain", "application/msword" });
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TITLE, "foobar.txt");
startActivityForResult(intent, 42);
});
view.addView(button);
+ button = new Button(context);
+ button.setText("GET_CONTENT */*");
+ button.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("*/*");
+ if (multiple.isChecked()) {
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+ }
+ startActivityForResult(Intent.createChooser(intent, "Kittens!"), 42);
+ }
+ });
+ view.addView(button);
+
mResult = new TextView(context);
view.addView(mResult);
is = getContentResolver().openInputStream(uri);
final int length = Streams.readFullyNoClose(is).length;
Log.d(TAG, "read length=" + length);
- } catch (IOException e) {
+ } catch (Exception e) {
Log.w(TAG, "Failed to read " + uri, e);
} finally {
IoUtils.closeQuietly(is);
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.util.Log;
import android.view.View;
import com.android.systemui.R;
public class BarTransitions {
+ private static final boolean DEBUG = false;
public static final int MODE_NORMAL = 0;
public static final int MODE_TRANSIENT = 1;
public static final int MODE_TRANSPARENT = 2;
+ private final String mTag;
private final View mTarget;
private final Drawable mOpaque;
private final Drawable mTransient;
private int mMode;
public BarTransitions(Context context, View target, Drawable transparent) {
+ mTag = "BarTransitions." + target.getClass().getSimpleName();
mTarget = target;
final Resources res = context.getResources();
mOpaque = new ColorDrawable(res.getColor(R.drawable.status_bar_background));
public void transitionTo(int mode) {
mMode = mode;
if (!ActivityManager.isHighEndGfx()) return;
+ if (DEBUG) Log.d(mTag, "transitionTo " + modeToString(mode));
Drawable background = mode == MODE_TRANSIENT ? mTransient
: mode == MODE_TRANSPARENT ? mTransparent
: mOpaque;
mTarget.setBackground(background);
}
+
+ public static String modeToString(int mode) {
+ if (mode == MODE_NORMAL) return "MODE_NORMAL";
+ if (mode == MODE_TRANSIENT) return "MODE_TRANSIENT";
+ if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
+ throw new IllegalArgumentException("Unknown mode " + mode);
+ }
}
--- /dev/null
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+import android.app.StatusBarManager;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Slog;
+import android.view.View;
+import android.view.WindowManagerPolicy.WindowState;
+
+import com.android.internal.statusbar.IStatusBarService;
+
+import java.io.PrintWriter;
+
+/**
+ * Controls state/behavior specific to a system bar window.
+ */
+public class BarController {
+ private static final boolean DEBUG = false;
+
+ private static final int TRANSIENT_BAR_NONE = 0;
+ private static final int TRANSIENT_BAR_SHOWING = 1;
+ private static final int TRANSIENT_BAR_HIDING = 2;
+
+ private final String mTag;
+ private final int mTransientFlag;
+ private final int mStatusBarManagerId;
+ private final Handler mHandler;
+ private final Object mServiceAquireLock = new Object();
+ private IStatusBarService mStatusBarService;
+
+ private WindowState mWin;
+ private int mTransientBarState;
+ private boolean mPendingShow;
+
+ public BarController(String tag, int transientFlag, int statusBarManagerId) {
+ mTag = "BarController." + tag;
+ mTransientFlag = transientFlag;
+ mStatusBarManagerId = statusBarManagerId;
+ mHandler = new Handler();
+ }
+
+ public void setWindow(WindowState win) {
+ mWin = win;
+ }
+
+ public void showTransient() {
+ if (mWin != null) {
+ setTransientBarState(TRANSIENT_BAR_SHOWING);
+ }
+ }
+
+ public boolean isTransientShowing() {
+ return mTransientBarState == TRANSIENT_BAR_SHOWING;
+ }
+
+ public void adjustSystemUiVisibilityLw(int visibility) {
+ if (mWin != null && mTransientBarState == TRANSIENT_BAR_SHOWING &&
+ (visibility & mTransientFlag) == 0) {
+ setTransientBarState(TRANSIENT_BAR_HIDING);
+ setBarShowingLw(false);
+ }
+ }
+
+ public boolean setBarShowingLw(final boolean show) {
+ if (mWin == null) return false;
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.setWindowState(mStatusBarManagerId, show
+ ? StatusBarManager.WINDOW_STATE_SHOWING
+ : StatusBarManager.WINDOW_STATE_HIDING);
+ }
+ } catch (RemoteException e) {
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
+ }
+ }
+ });
+ if (show && mTransientBarState == TRANSIENT_BAR_HIDING) {
+ mPendingShow = true;
+ return false;
+ }
+ return show ? mWin.showLw(true) : mWin.hideLw(true);
+ }
+
+ public boolean checkHiddenLw() {
+ if (mWin != null && mTransientBarState == TRANSIENT_BAR_HIDING && !mWin.isVisibleLw()) {
+ // Finished animating out, clean up and reset style
+ setTransientBarState(TRANSIENT_BAR_NONE);
+ if (mPendingShow) {
+ setBarShowingLw(true);
+ mPendingShow = false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public boolean checkShowTransientBarLw() {
+ if (mTransientBarState == TRANSIENT_BAR_SHOWING) {
+ if (DEBUG) Slog.d(mTag, "Not showing transient bar, already shown");
+ return false;
+ } else if (mWin == null) {
+ if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar doesn't exist");
+ return false;
+ } else if (mWin.isDisplayedLw()) {
+ if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar already visible");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public int updateVisibilityLw(boolean allowed, int oldVis, int vis) {
+ if (mWin == null) return vis;
+
+ if (mTransientBarState == TRANSIENT_BAR_SHOWING) { // transient bar requested
+ if (allowed) {
+ vis |= mTransientFlag;
+ if ((oldVis & mTransientFlag) == 0) {
+ setBarShowingLw(true);
+ }
+ } else {
+ setTransientBarState(TRANSIENT_BAR_NONE); // request denied
+ }
+ }
+ if (mTransientBarState != TRANSIENT_BAR_NONE) {
+ vis |= mTransientFlag; // ignore clear requests until transition completes
+ vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE; // never show transient bars in low profile
+ }
+ return vis;
+ }
+
+ private void setTransientBarState(int state) {
+ if (mWin != null && state != mTransientBarState) {
+ mTransientBarState = state;
+ if (DEBUG) Slog.d(mTag, "New state: " + transientBarStateToString(state));
+ }
+ }
+
+ private IStatusBarService getStatusBarService() {
+ synchronized (mServiceAquireLock) {
+ if (mStatusBarService == null) {
+ mStatusBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService("statusbar"));
+ }
+ return mStatusBarService;
+ }
+ }
+
+ private static String transientBarStateToString(int state) {
+ if (state == TRANSIENT_BAR_HIDING) return "TRANSIENT_BAR_HIDING";
+ if (state == TRANSIENT_BAR_SHOWING) return "TRANSIENT_BAR_SHOWING";
+ if (state == TRANSIENT_BAR_NONE) return "TRANSIENT_BAR_NONE";
+ throw new IllegalArgumentException("Unknown state " + state);
+ }
+
+ public void dump(PrintWriter pw, String prefix) {
+ if (mWin != null) {
+ pw.print(prefix); pw.print(mTag); pw.print(' ');
+ pw.print("mTransientBar"); pw.print('=');
+ pw.println(transientBarStateToString(mTransientBarState));
+ }
+ }
+}
}
MyOrientationListener mOrientationListener;
- private static final int TRANSIENT_BAR_NONE = 0;
- private static final int TRANSIENT_BAR_SHOWING = 1;
- private static final int TRANSIENT_BAR_HIDING = 2;
- private int mStatusTransientBar;
- private int mNavigationTransientBar;
+ private final BarController mStatusBarController = new BarController("StatusBar",
+ View.STATUS_BAR_TRANSIENT, StatusBarManager.WINDOW_STATUS_BAR);
+ private final BarController mNavigationBarController = new BarController("NavigationBar",
+ View.NAVIGATION_BAR_TRANSIENT, StatusBarManager.WINDOW_NAVIGATION_BAR);
private TransientNavigationConfirmation mTransientNavigationConfirmation;
private SystemGesturesPointerEventListener mSystemGestures;
}
}
mStatusBar = win;
+ mStatusBarController.setWindow(win);
break;
case TYPE_NAVIGATION_BAR:
mContext.enforceCallingOrSelfPermission(
}
}
mNavigationBar = win;
+ mNavigationBarController.setWindow(win);
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
case TYPE_NAVIGATION_BAR_PANEL:
public void removeWindowLw(WindowState win) {
if (mStatusBar == win) {
mStatusBar = null;
+ mStatusBarController.setWindow(null);
} else if (mKeyguard == win) {
Log.v(TAG, "Removing keyguard window (Did it crash?)");
mKeyguard = null;
mKeyguardScrim = null;
} if (mNavigationBar == win) {
mNavigationBar = null;
+ mNavigationBarController.setWindow(null);
}
}
@Override
public int adjustSystemUiVisibilityLw(int visibility) {
- if (mStatusBar != null && mStatusTransientBar == TRANSIENT_BAR_SHOWING &&
- 0 == (visibility & View.STATUS_BAR_TRANSIENT)) {
- mStatusTransientBar = TRANSIENT_BAR_HIDING;
- setBarShowingLw(mStatusBar, false);
- }
- if (mNavigationBar != null && mNavigationTransientBar == TRANSIENT_BAR_SHOWING &&
- 0 == (visibility & View.NAVIGATION_BAR_TRANSIENT)) {
- mNavigationTransientBar = TRANSIENT_BAR_HIDING;
- setBarShowingLw(mNavigationBar, false);
- }
+ mStatusBarController.adjustSystemUiVisibilityLw(visibility);
+ mNavigationBarController.adjustSystemUiVisibilityLw(visibility);
+
// Reset any bits in mForceClearingStatusBarVisibility that
// are now clear.
mResettingSystemUiFlags &= visibility;
boolean updateSysUiVisibility = false;
if (mNavigationBar != null) {
- boolean transientNavBarShowing = mNavigationTransientBar == TRANSIENT_BAR_SHOWING;
+ boolean transientNavBarShowing = mNavigationBarController.isTransientShowing();
// Force the navigation bar to its appropriate place and
// size. We need to do this directly, instead of relying on
// it to bubble up from the nav bar, because this needs to
mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom);
mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top;
if (transientNavBarShowing || navTransparent) {
- setBarShowingLw(mNavigationBar, true);
+ mNavigationBarController.setBarShowingLw(true);
} else if (navVisible) {
- setBarShowingLw(mNavigationBar, true);
+ mNavigationBarController.setBarShowingLw(true);
mDockBottom = mTmpNavigationFrame.top;
mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop;
mRestrictedOverscanScreenHeight = mDockBottom - mRestrictedOverscanScreenTop;
} else {
// We currently want to hide the navigation UI.
- setBarShowingLw(mNavigationBar, false);
+ mNavigationBarController.setBarShowingLw(false);
}
if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()) {
// If the opaque nav bar is currently requested to be visible,
mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight);
mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
if (transientNavBarShowing || navTransparent) {
- setBarShowingLw(mNavigationBar, true);
+ mNavigationBarController.setBarShowingLw(true);
} else if (navVisible) {
- setBarShowingLw(mNavigationBar, true);
+ mNavigationBarController.setBarShowingLw(true);
mDockRight = mTmpNavigationFrame.left;
mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft;
mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft;
} else {
// We currently want to hide the navigation UI.
- setBarShowingLw(mNavigationBar, false);
+ mNavigationBarController.setBarShowingLw(false);
}
if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()) {
// If the nav bar is currently requested to be visible,
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame);
if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
- if (mNavigationTransientBar == TRANSIENT_BAR_HIDING && !mNavigationBar.isVisibleLw()) {
- // Finished animating out, clean up and reset alpha
- mNavigationTransientBar = TRANSIENT_BAR_NONE;
+ if (mNavigationBarController.checkHiddenLw()) {
updateSysUiVisibility = true;
}
}
// we can tell the app that it is covered by it.
mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
}
-
- if (mStatusTransientBar == TRANSIENT_BAR_HIDING && !mStatusBar.isVisibleLw()) {
- // Finished animating out, clean up and reset alpha
- mStatusTransientBar = TRANSIENT_BAR_NONE;
+ if (mStatusBarController.checkHiddenLw()) {
updateSysUiVisibility = true;
}
}
+ " top=" + mTopFullscreenOpaqueWindowState);
if (mForceStatusBar || mForceStatusBarFromKeyguard) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced");
- if (setBarShowingLw(mStatusBar, true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (mStatusBarController.setBarShowingLw(true)) {
+ changes |= FINISH_LAYOUT_REDO_LAYOUT;
+ }
} else if (mTopFullscreenOpaqueWindowState != null) {
if (localLOGV) {
Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
// and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
// has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
// case though.
- if (mStatusTransientBar == TRANSIENT_BAR_SHOWING) {
- if (setBarShowingLw(mStatusBar, true)) {
+ if (mStatusBarController.isTransientShowing()) {
+ if (mStatusBarController.setBarShowingLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT;
}
} else if (topIsFullscreen) {
if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar");
- if (setBarShowingLw(mStatusBar, false)) {
+ if (mStatusBarController.setBarShowingLw(false)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT;
} else {
if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding");
}
} else {
if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen");
- if (setBarShowingLw(mStatusBar, true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (mStatusBarController.setBarShowingLw(true)) {
+ changes |= FINISH_LAYOUT_REDO_LAYOUT;
+ }
}
}
}
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
- if (isScreenOn && isNavigationBarTransient(mLastSystemUiFlags)) {
+ if (isScreenOn && isTransientNavigationAllowed(mLastSystemUiFlags)) {
mTransientNavigationConfirmation.unconfirmLastPackage();
}
if (isScreenOn && !mPowerKeyTriggered
private void requestTransientBars(WindowState swipeTarget) {
synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
- boolean sb = checkShowTransientBar("status", mStatusTransientBar, mStatusBar);
- boolean nb = checkShowTransientBar("nav", mNavigationTransientBar, mNavigationBar);
+ boolean sb = mStatusBarController.checkShowTransientBarLw();
+ boolean nb = mNavigationBarController.checkShowTransientBarLw();
if (sb || nb) {
WindowState barTarget = sb ? mStatusBar : mNavigationBar;
if (sb ^ nb && barTarget != swipeTarget) {
if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
return;
}
- mStatusTransientBar = sb ? TRANSIENT_BAR_SHOWING : mStatusTransientBar;
- mNavigationTransientBar = nb ? TRANSIENT_BAR_SHOWING : mNavigationTransientBar;
+ if (sb) mStatusBarController.showTransient();
+ if (nb) mNavigationBarController.showTransient();
updateSystemUiVisibilityLw();
}
}
}
- private boolean checkShowTransientBar(String tag, int transientBar, WindowState win) {
- if (transientBar == TRANSIENT_BAR_SHOWING) {
- if (DEBUG) Slog.d(TAG, "Not showing " + tag + " transient bar, already shown");
- return false;
- } else if (win == null) {
- if (DEBUG) Slog.d(TAG, "Not showing " + tag + " transient bar, bar doesn't exist");
- return false;
- } else if (win.isDisplayedLw()) {
- if (DEBUG) Slog.d(TAG, "Not showing " + tag + " transient bar, bar already visible");
- return false;
- } else {
- return true;
- }
- }
-
@Override
public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0);
if (ImmersiveModeTesting.enabled) {
vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
}
+
+ // prevent status bar interaction from clearing certain flags
boolean statusBarHasFocus = mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
if (statusBarHasFocus) {
- // prevent status bar interaction from clearing certain flags
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT;
vis = (vis & ~flags) | (mLastSystemUiFlags & flags);
}
- if (mStatusTransientBar == TRANSIENT_BAR_SHOWING) {
- // status transient bar requested
- boolean transientAllowed =
- (vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
- boolean hideStatusBarWM =
- (mFocusedWindow.getAttrs().flags
- & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
- boolean hideStatusBarSysui =
- (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
-
- boolean transientStatusBarAllowed =
- hideStatusBarWM
- || (hideStatusBarSysui && transientAllowed)
- || statusBarHasFocus;
-
- if (mStatusBar == null || !transientStatusBarAllowed) {
- mStatusTransientBar = TRANSIENT_BAR_NONE;
- if (mStatusBar != null && hideStatusBarSysui) {
- // clear the clearable flags instead
- int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
- if (newVal != mResettingSystemUiFlags) {
- mResettingSystemUiFlags = newVal;
- mWindowManagerFuncs.reevaluateStatusBarVisibility();
- }
- }
- } else {
- // show status transient bar
- vis |= View.STATUS_BAR_TRANSIENT;
- if ((mLastSystemUiFlags & View.STATUS_BAR_TRANSIENT) == 0) {
- vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
- setBarShowingLw(mStatusBar, true);
- }
+
+ // update status bar
+ boolean transientAllowed =
+ (vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
+ boolean hideStatusBarWM =
+ (mFocusedWindow.getAttrs().flags
+ & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
+ boolean hideStatusBarSysui =
+ (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
+
+ boolean transientStatusBarAllowed =
+ mStatusBar != null && (
+ hideStatusBarWM
+ || (hideStatusBarSysui && transientAllowed)
+ || statusBarHasFocus);
+
+ if (mStatusBarController.isTransientShowing()
+ && !transientStatusBarAllowed && hideStatusBarSysui) {
+ // clear the clearable flags instead
+ int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
+ if (newVal != mResettingSystemUiFlags) {
+ mResettingSystemUiFlags = newVal;
+ mWindowManagerFuncs.reevaluateStatusBarVisibility();
}
}
- boolean oldTransientNav = isNavigationBarTransient(oldVis);
- boolean isTransientNav = isNavigationBarTransient(vis);
+
+ vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis);
+
+ // update navigation bar
+ boolean oldTransientNav = isTransientNavigationAllowed(oldVis);
+ boolean isTransientNav = isTransientNavigationAllowed(vis);
if (mFocusedWindow != null && oldTransientNav != isTransientNav) {
final int uid = getCurrentUserId();
final String pkg = mFocusedWindow.getOwningPackage();
mTransientNavigationConfirmation.transientNavigationChanged(uid, pkg, isTransientNav);
}
- if (mNavigationTransientBar == TRANSIENT_BAR_SHOWING) {
- // navigation transient bar requested
- if (!isTransientNav) {
- mNavigationTransientBar = TRANSIENT_BAR_NONE;
- } else {
- // show navigation transient bar
- vis |= View.NAVIGATION_BAR_TRANSIENT;
- if ((mLastSystemUiFlags & View.NAVIGATION_BAR_TRANSIENT) == 0) {
- setBarShowingLw(mNavigationBar, true);
- }
- }
- }
- if (mStatusTransientBar != TRANSIENT_BAR_NONE
- || mNavigationTransientBar != TRANSIENT_BAR_NONE) {
- vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
- }
+ vis = mNavigationBarController.updateVisibilityLw(isTransientNav, oldVis, vis);
+
return vis;
}
- private boolean isNavigationBarTransient(int vis) {
+ private boolean isTransientNavigationAllowed(int vis) {
return mNavigationBar != null
&& (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
&& (vis & View.SYSTEM_UI_FLAG_ALLOW_TRANSIENT) != 0;
}
- private boolean setBarShowingLw(WindowState win, final boolean show) {
- final int window =
- win == mStatusBar ? StatusBarManager.WINDOW_STATUS_BAR
- : win == mNavigationBar ? StatusBarManager.WINDOW_NAVIGATION_BAR
- : 0;
- if (window != 0) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.setWindowState(window, show
- ? StatusBarManager.WINDOW_STATE_SHOWING
- : StatusBarManager.WINDOW_STATE_HIDING);
- }
- } catch (RemoteException e) {
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
- }
- }
- });
- }
- return show ? win.showLw(true) : win.hideLw(true);
- }
-
// Temporary helper that allows testing immersive mode on existing apps
// TODO remove
private static final class ImmersiveModeTesting {
pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation);
pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation);
- dumpTransient(pw, prefix,
- mStatusBar, "mStatusTransientBar", mStatusTransientBar);
- dumpTransient(pw, prefix,
- mNavigationBar, "mNavigationTransientBar", mNavigationTransientBar);
- }
-
- private void dumpTransient(PrintWriter pw, String pre, WindowState win, String var, int val) {
- if (win != null) {
- pw.print(pre); pw.print(var); pw.print('=');
- pw.println(val == TRANSIENT_BAR_HIDING ? "HIDING"
- : val == TRANSIENT_BAR_SHOWING ? "SHOWING"
- : "NONE");
- }
+ mStatusBarController.dump(pw, prefix);
+ mNavigationBarController.dump(pw, prefix);
}
}
if (haveSizeBias) {
*outSize += sizeBias;
}
+ if (*outSize < 0) {
+ *outSize = 0;
+ }
}
} mCalibration;
Log.d(TAG, "Event [" + eventStr + "]");
}
+ String iface = "p2p0";
WifiMonitor m = null;
mStateMachine = null;
if (eventStr.startsWith("IFNAME=")) {
int space = eventStr.indexOf(' ');
if (space != -1) {
- String iface = eventStr.substring(7,space);
+ iface = eventStr.substring(7,space);
m = mWifiMonitorSingleton.getMonitor(iface);
if (m == null && iface.startsWith("p2p-")) {
// p2p interfaces are created dynamically, but we have
// for it explicitly, and send messages there ..
m = mWifiMonitorSingleton.getMonitor("p2p0");
}
- if (m != null) {
- if (m.mMonitoring) {
- mStateMachine = m.mWifiStateMachine;
- eventStr = eventStr.substring(space + 1);
- }
- else {
- if (DBG) Log.d(TAG, "Dropping event because monitor (" + iface +
- ") is stopped");
- continue;
- }
- }
- else {
- eventStr = eventStr.substring(space + 1);
- }
+ eventStr = eventStr.substring(space + 1);
+ }
+ } else {
+ // events without prefix belong to p2p0 monitor
+ m = mWifiMonitorSingleton.getMonitor("p2p0");
+ }
+
+ if (m != null) {
+ if (m.mMonitoring) {
+ mStateMachine = m.mWifiStateMachine;
+ } else {
+ if (DBG) Log.d(TAG, "Dropping event because monitor (" + iface +
+ ") is stopped");
+ continue;
}
}