Code Monkey home page Code Monkey logo

amitshekhariitbhu / android-debug-database Goto Github PK

View Code? Open in Web Editor NEW
8.3K 8.3K 871.0 1.6 MB

A library for debugging android databases and shared preferences - Make Debugging Great Again

Home Page: https://amitshekhar.me

License: Apache License 2.0

Java 74.00% JavaScript 22.04% CSS 0.53% HTML 3.43%
android android-debug-database awesome database database-values debug debugging emulator room room-database room-persistence-library sharedpreferences sqlite

android-debug-database's Introduction

Android Debug Database

Android Debug Database is a powerful library for debugging databases and shared preferences in Android applications

Android Debug Database allows you to view databases and shared preferences directly in your browser in a very simple way

What can Android Debug Database do?

  • See all the databases.
  • See all the data in the shared preferences used in your application.
  • Run any sql query on the given database to update and delete your data.
  • Directly edit the database values.
  • Directly edit the shared preferences.
  • Directly add a row in the database.
  • Directly add a key-value in the shared preferences.
  • Delete database rows and shared preferences.
  • Search in your data.
  • Sort data.
  • Download database.
  • Debug Room inMemory database.

About me

Hi, I am Amit Shekhar, I have mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

You can connect with me on:

My Personal Blog - amitshekhar.me - High-quality content to learn Android concepts.

All these features work without rooting your device -> No need of rooted device

Using Android Debug Database Library in your application

Add this to your app's build.gradle

debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'

Using the Android Debug Database with encrypted database

debugImplementation 'com.amitshekhar.android:debug-db-encrypt:1.0.6'

And to provide the password for the DB, you should add this in the Gradle: DB_PASSWORD_{VARIABLE}, if for example, PERSON is the database name: DB_PASSWORD_PERSON

debug {
    resValue("string", "DB_PASSWORD_PERSON", "password")
}

Use debugImplementation so that it will only compile in your debug build and not in your release build.

That’s all, just start the application, you will see in the logcat an entry like follows :

  • D/DebugDB: Open http://XXX.XXX.X.XXX:8080 in your browser

  • You can also always get the debug address url from your code by calling the method DebugDB.getAddressLog();

Now open the provided link in your browser.

Important:

  • Your Android phone and laptop should be connected to the same Network (Wifi or LAN).
  • If you are using it over usb, run adb forward tcp:8080 tcp:8080

Note : If you want use different port other than 8080. In the app build.gradle file under buildTypes do the following change

debug {
    resValue("string", "PORT_NUMBER", "8081")
}

You will see something like this :

Seeing values

Editing values

Working with emulator

  • Android Default Emulator: Run the command in the terminal - adb forward tcp:8080 tcp:8080 and open http://localhost:8080
  • Genymotion Emulator: Enable bridge from configure virtual device (option available in genymotion)

Getting address with toast, in case you missed the address log in logcat

As this library is auto-initialize, if you want to get the address log, add the following method and call (we have to do like this to avoid build error in release build as this library will not be included in the release build) using reflection.

public static void showDebugDBAddressLogToast(Context context) {
    if (BuildConfig.DEBUG) {
       try {
            Class<?> debugDB = Class.forName("com.amitshekhar.DebugDB");
            Method getAddressLog = debugDB.getMethod("getAddressLog");
            Object value = getAddressLog.invoke(null);
            Toast.makeText(context, (String) value, Toast.LENGTH_LONG).show();
       } catch (Exception ignore) {

       }
    }
}

Adding custom database files

As this library is auto-initialize, if you want to debug custom database files, add the following method and call

public static void setCustomDatabaseFiles(Context context) {
    if (BuildConfig.DEBUG) {
        try {
            Class<?> debugDB = Class.forName("com.amitshekhar.DebugDB");
            Class[] argTypes = new Class[]{HashMap.class};
            Method setCustomDatabaseFiles = debugDB.getMethod("setCustomDatabaseFiles", argTypes);
            HashMap<String, Pair<File, String>> customDatabaseFiles = new HashMap<>();
            // set your custom database files
            customDatabaseFiles.put(ExtTestDBHelper.DATABASE_NAME,
                    new Pair<>(new File(context.getFilesDir() + "/" + ExtTestDBHelper.DIR_NAME +
                                                    "/" + ExtTestDBHelper.DATABASE_NAME), ""));
            setCustomDatabaseFiles.invoke(null, customDatabaseFiles);
        } catch (Exception ignore) {

        }
    }
}

Adding InMemory Room databases

As this library is auto-initialize, if you want to debug inMemory Room databases, add the following method and call

public static void setInMemoryRoomDatabases(SupportSQLiteDatabase... database) {
    if (BuildConfig.DEBUG) {
        try {
            Class<?> debugDB = Class.forName("com.amitshekhar.DebugDB");
            Class[] argTypes = new Class[]{HashMap.class};
            HashMap<String, SupportSQLiteDatabase> inMemoryDatabases = new HashMap<>();
            // set your inMemory databases
            inMemoryDatabases.put("InMemoryOne.db", database[0]);
            Method setRoomInMemoryDatabase = debugDB.getMethod("setInMemoryRoomDatabases", argTypes);
            setRoomInMemoryDatabase.invoke(null, inMemoryDatabases);
        } catch (Exception ignore) {

        }
    }
}

Find this project useful ? ❤️

  • Support it by clicking the ⭐ button on the upper right of this page. ✌️

TODO

  • Simplify emulator issue Issue Link
  • And of course many more features and bug fixes.

You can connect with me on:

Read all of my blogs here.

License

   Copyright (C) 2022 Amit Shekhar

   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.

Contributing to Android Debug Database

All pull requests are welcome, make sure to follow the contribution guidelines when you submit pull request.

android-debug-database's People

Contributors

agravelot avatar amitshekhariitbhu avatar anandgaurav10 avatar codebymikey avatar friederbluemle avatar haofei91 avatar mstarita avatar myz6 avatar rajengla avatar realjustinwu avatar remcomokveld avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-debug-database's Issues

http://0.0.0.0:8080 is shown for real phone

When I use my smart phone as AP and let my laptop connect to it, the link will be http://0.0.0.0:8080 and it cannot show anything.

The simplest solution I found is change the URL to router's ip address, for example, http://192.168.1.1:8080, and then it will work. Can you make the address show in the logcat?

Relayout navigation to breadcrumbs UX pattern

Hi Amit,

What you think about changing navigation to breadcrumbs UX pattern (something like [Home] -> [Database] -> [Table] in the top of the screen with popups for database or table selection)?

breadcrumbs

So it gives more spacing for content of tables with more than several columns (my case :) )

Realm support?

Great work on the library!
I was wondering if this library has Realm support? Since, Realm browser app ( where you can see realm database ) is available only on Mac, it would be great to have Realm support for this library.

Cheers

It always open a html which is in my project

There is a html in my project,and then it always go to the html when i try to open the address that printed in the console. I try to change the port,but it does't worked.I am confused.

How can I contribute to this repository?

Hi, I am Devendra, a Java Developer and Android Enthusiast, I have used this library in one of my android projects and its great. I want to be part of development. Let me know, how can I do it?

Database Version

It would be great to have a feature to check the database version (PRAGMA user_version), which could be used in migrations.

can't query having '%' string

may be fix javscript code

$.ajax({url: "query?query="+escape(query), success: function(result){

       result = JSON.parse(result);
       inflateData(result);

}});

java.lang.NullPointerException: Attempt to get length of null array

java.lang.NullPointerException: Attempt to get length of null array
  at com.amitshekhar.server.ClientServer.getDBList(ClientServer.java:412)
  at com.amitshekhar.server.ClientServer.handle(ClientServer.java:216)
  at com.amitshekhar.server.ClientServer.run(ClientServer.java:128)
  at java.lang.Thread.run(Thread.java:818)

The culprit seems to be the following line.

mDatabaseDir.list() is returning null because

If this abstract pathname does not denote a directory, then this method returns null.

https://docs.oracle.com/javase/7/docs/api/java/io/File.html#list()

Although unlikely to happen (if you're choosing to use this library, you probably already have the database ready), it would be nicer if it could handle the edge-case accordingly.

App crash when I open url in browser

I added dependency debugCompile 'com.amitshekhar.android:debug-db:0.4.0' and run android app it's running well. but when I open http://192.168.1.19:8080/ in browser app crash with below log.
192.168.1.19 is device ip.
Device: Moto G Turbo running on Android 6.0.1

FATAL EXCEPTION: Thread-21799
Process: com.xxxxx, PID: 5228
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.FileDescriptor.setInt$(int)' on a null object reference
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:93)
at java.net.ServerSocket.implAccept(ServerSocket.java:217)
at java.net.ServerSocket.accept(ServerSocket.java:141)
at com.amitshekhar.server.ClientServer.run(ClientServer.java:126)
at java.lang.Thread.run(Thread.java:818)

ip adress issues

some times receive the Ip is 192.168.199.240, This will not open the database. My local Ip is 192.168.2.xx.

NullPointerException

      java.lang.NullPointerException: Attempt to get length of null array
      at com.amitshekhar.server.ClientServer.getDBList(ClientServer.java:412)
      at com.amitshekhar.server.ClientServer.handle(ClientServer.java:216)
       at com.amitshekhar.server.ClientServer.run(ClientServer.java:128)
      at java.lang.Thread.run(Thread.java:818)

Order by with query not working

Hi ,

When I use order by clause it is not showing desired result ,But correct data is shown after UI table column sorting.

db

db2

Thank you for useful library

[Feature request] Files management

Hey,

great tool! I treat it as a central place to get data from the app during my development. Although it would be nice to have files management as well. Files stored in the application's files directory could be:

  • viewable
  • deletable
  • uploadable

What do you think about it? Do you have any plans? Is this kind of contribution possibly welcome?

App crashes when I try to load provided URL

Hi,

Saw your post on Medium and thought I would try this out but I am not having much luck. When the app starts up I see the URL but when i try to open, the app crashes and the following error is displayed:

E/AndroidRuntime: FATAL EXCEPTION: Thread-49637 Process: <app.id>, PID: 8713 java.lang.NullPointerException: Attempt to get length of null array at com.amitshekhar.server.ClientServer.getDBList(ClientServer.java:412) at com.amitshekhar.server.ClientServer.handle(ClientServer.java:216) at com.amitshekhar.server.ClientServer.run(ClientServer.java:128) at java.lang.Thread.run(Thread.java:818) E/AbstractTracker: Can't create handler inside thread that has not called Looper.prepare() E/AbstractTracker: mTrackerAsyncQueryHandler is null

Do you know what the error issue might be. Not sure if its related but I am using DBFlow ORM.

No data shown on the panel and Exception

I have a problem with showing the data of the emulator.

I was following those steps:

  • i added the dependency
  • i made this: adb forward tcp:8080 tcp:8080 in my terminal
  • after that i was able to see the panel at: http://localhost:8080

But when i go to this address it shows just nothing, but a blank panel with no data:
debug-database

I also get this Exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference 07-30 00:31:54.978 16077-16159/com.okset.realmsample W/System.err: at com.amitshekhar.utils.DatabaseHelper.getTableData(DatabaseHelper.java:83) 07-30 00:31:54.979 16077-16159/com.okset.realmsample W/System.err: at com.amitshekhar.server.RequestHandler.executeQueryAndGetResponse(RequestHandler.java:235) 07-30 00:31:54.979 16077-16159/com.okset.realmsample W/System.err: at com.amitshekhar.server.RequestHandler.handle(RequestHandler.java:118) 07-30 00:31:54.979 16077-16159/com.okset.realmsample W/System.err: at com.amitshekhar.server.ClientServer.run(ClientServer.java:78)

Why i cannot see any database?

Not Working on Genymotion

Hi, it is not working on my end. It keeps loading the web page. It is said in the log:

D/DebugDB: Open http://10.0.3.15:8081 in your browser

But it was loading then said that the site can't be reached. Is there anything wrong?
FYI, i use kotlin and there is no java folder inside src. Another info:

  • Min sdk is 15
  • Compile sdk is 25
  • build tools version 25.0.0
  • target sdk 25
  • tested on Genymotion 4.1.1

Please help, thanks!

Export .db file

Awesome library for unrooted device!

Can we actually export the .db file to somewhere?

It seems can not load any data?

I think this project is great, so I write a test app to see it's feature.
I'm sure my phone and my computer are in the same WIFI.
When open the browser, just like this, it has a welcome button, can't see my DB, what's wrong?
image

Integer overflow?

Large INTEGER columns seem to overflow, showing negative number instead of the real value

sqlite> .schema user
CREATE TABLE USER (
id INTEGER PRIMARY KEY AUTOINCREMENT,
createdAt INTEGER NOT NULL,
  ...

Pulling the .db manually and querying

sqlite> select createdAt from user where id=112;
createdAt
1480519860000

DebugDB shows that same cell with value -1243857120

Pragma doesn't work

Hi,

If I try to execute query like PRAGMA table_info(myTable); I'll get error.
Root cause is in DatabaseHelper class in method executeQueryAndGetResponse.
It checks if first word in query is "select" and does query otherwise does execSql which doesn't support results.

I think this could be solved by checking for "pragma" as well and in that case executing "getTableInfo" method.

gradle version is too high.

This is a very practical projects, but I think the gradle compiled version is too high, lead to low version of the project can't compatible.

So if it can in low version?

How can i use this in my project, which is not a Android studio project?

Hi, guys! Please help!
For me, my project is not AS(Android Studio) project and is not complied by gradle. It's an android source code project complied with Android.mk. And I don't have right to update the project to android studio project.
I cloned the code and complied it, now I have debug-db-debug.arr and debug-db-release.aar. I can add aar file into Android.mk as static lib, but what should I do in my java code?
What should I import and how to init DebugDB? port ?

Edit and Delete rows have errors

i cannot delete a row.. it shows deleted successfully but when i click again on the table name it shows the deleted row.. when i edited a column value whole table got updated to the new row(redundant rows). help me with this.

display encrypted data

I try to use it, but shows the encrypted data.
GCmsAMnORmFEE75OR97CBy5Yx3sVp/GEXKuHxneFKdJhTAAPHo1loI64bKGIMSmCha3Q8bFl1+Uqfss73UkHIMJf44lEW5pD6Kitvu1UrYcLpe8xm68uP2wA09Z+AbhvaBg40E6E3S8m852ZBeuKp0r+quPvEzwlZOrCd3VZYxhpIQOC+W1UHOiCitAoVibVrtMjvMQc4mhLZm9cC42RsOsXXGUt9Obb8hjJrRzWz6KulqMaCc4ieKgOqFFoPcmTgu0aF8aA2h41kMGw1XRMXJXei7+X9vRjm+uqVmRQUa5mIDJUTzDIwbLW9HZU2KwLh0PGd6gYnN8U8nQBuhf53R9J7douOR1nRH2rPAzb5ROBfdjXFqmVg5A+GuF6yiL9bEC+NzQZ7tTQCFVtCvA1jttCUh4+xp2p8c00iElI8W1tdh3Ay038WeIxjKqNJ6o3crayCPZn5A4GkUb54Zm6VQsiV1xhKR5SyyJ0P5qnZDle/Ogoo1/RcDwvGi0582LrlGsJ7ymkcLYskConFrcZOEX/x4YB10Khw5Pzl5aCkt608wLxofsTlqa/DpiRU32mjhzyWdrCG9kCiMBhDUNr9DXNJ68ypscwd7OsVherTFV+XvZDQBOnm4575+Y4YCgzPvUrJ8o77M8l9m+vo5uvM2DTVFiy4tdoDeQd13CfZIWHFuW9TNn6rkmN75rAtWd5hRH1pTRgEw1dVyfP9KXE9KhjZiLD/fs/lnGm6Yu7QTbDAAf6ujv0QHZJCsARNZFk1x4S4js3VElpeTbdS0jZCAwMx5fad7Vg7xV2Sbo1hQwwjQYLi2vhOh5U8mNyja+D/4DZiU6Ss4qu15Ub2kmgIdfQEHA1lR4jlt+7lQgi1stCqZk/aSq/xHcoPPt1c0/ruphUo6YSgX9j+eObUMxK5yhc5uc7I3AhEAdpIhYBkalDe40IKTE4lSyBJr21lNogNO1nVRVfu9cCKSkl6rWFIeJzGALVkxzPII4HzLFmRu8/ox8wBCOXfZOzG0gsfFeGAYfHCiY+nIRrapCTgz1Lmi87kn/JRpjNR5tl6rj2VHYi+dj8EDVEiLRoaNehA83XcBKcEINKuQXb9El23OgHMM2Bw9wUE/8z7qmQ8vMfJjawaN0kpzOI0aXj2IYd4q4JLKk1t8yVfLJ25D9jEcBcuA==

Can't see custom database location?

It seems you take DBs from com.package.packagename/databases/
My DB location is in com.package.packagename/files/myfolder/mydatabase.db .
So, How can I see for custom database. Thanks

If there is a subdirectory in /data/data/myapp/databases, than it doesn't work

It just throw an exception like this :

E/SQLiteLog: (14) cannot open file at line 30058 of [9491ba7d73]
E/SQLiteLog: (14) os_unix.c:30058: (21) open(/data/data/myapp/databases/cc) -
E/SQLiteConnection: DB info: sqlite3_open_v2, path: /data/data/myapp/databases/cc, flag: 6, ret: 14
E/SQLiteConnection: DB info: errno = 21, errno message = Is a directory
E/SQLiteDatabase: Failed to open database '/data/data/myapp/databases/cc'.

Although I can open the web, it only show databases's name, you can't see the data.
It seems the lib deals with dir as a database, and cause everything broken after.

Library not working if table name is a reserved keyword.

Made a table with name "transaction" in my app, and library crashes when i request that table.

Stack trace:

03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile E/SQLiteLog: (1) near "transaction": syntax error
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err: android.database.sqlite.SQLiteException: near "transaction": syntax error (code 1): , while compiling: SELECT * FROM transaction
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at com.amitshekhar.utils.DatabaseHelper.getTableData(DatabaseHelper.java:80)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at com.amitshekhar.server.RequestHandler.getAllDataFromTheTableResponse(RequestHandler.java:197)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at com.amitshekhar.server.RequestHandler.handle(RequestHandler.java:102)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at com.amitshekhar.server.ClientServer.run(ClientServer.java:75)
03-29 10:01:47.594 30095-30114/in.shipsy.riderapp.firstmile W/System.err:     at java.lang.Thread.run(Thread.java:841)

I'd like to fix this bug. Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.